1511b41d2SMark Murray /* 2511b41d2SMark Murray * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3511b41d2SMark Murray * All rights reserved 4511b41d2SMark Murray * 5c2d3a559SKris Kennaway * As far as I am concerned, the code I have written for this software 6c2d3a559SKris Kennaway * can be used freely for any purpose. Any derived versions of this 7c2d3a559SKris Kennaway * software must be clearly marked as such, and if the derived work is 8c2d3a559SKris Kennaway * incompatible with the protocol description in the RFC file, it must be 9c2d3a559SKris Kennaway * called by a name other than "ssh" or "Secure Shell". 10511b41d2SMark Murray */ 11511b41d2SMark Murray 12511b41d2SMark Murray #include "includes.h" 1309958426SBrian Feldman RCSID("$OpenBSD: servconf.c,v 1.53 2000/10/14 12:12:09 markus Exp $"); 14c2d3a559SKris Kennaway RCSID("$FreeBSD$"); 15511b41d2SMark Murray 16511b41d2SMark Murray #include "ssh.h" 17511b41d2SMark Murray #include "servconf.h" 18511b41d2SMark Murray #include "xmalloc.h" 19e8aafc91SKris Kennaway #include "compat.h" 20511b41d2SMark Murray 21511b41d2SMark Murray /* add listen address */ 22511b41d2SMark Murray void add_listen_addr(ServerOptions *options, char *addr); 23511b41d2SMark Murray 24511b41d2SMark Murray /* Initializes the server options to their default values. */ 25511b41d2SMark Murray 26511b41d2SMark Murray void 27511b41d2SMark Murray initialize_server_options(ServerOptions *options) 28511b41d2SMark Murray { 29511b41d2SMark Murray memset(options, 0, sizeof(*options)); 30511b41d2SMark Murray options->num_ports = 0; 31511b41d2SMark Murray options->ports_from_cmdline = 0; 32511b41d2SMark Murray options->listen_addrs = NULL; 33511b41d2SMark Murray options->host_key_file = NULL; 34e8aafc91SKris Kennaway options->host_dsa_key_file = NULL; 35e8aafc91SKris Kennaway options->pid_file = NULL; 36511b41d2SMark Murray options->server_key_bits = -1; 37511b41d2SMark Murray options->login_grace_time = -1; 38511b41d2SMark Murray options->key_regeneration_time = -1; 39511b41d2SMark Murray options->permit_root_login = -1; 40511b41d2SMark Murray options->ignore_rhosts = -1; 41511b41d2SMark Murray options->ignore_user_known_hosts = -1; 42511b41d2SMark Murray options->print_motd = -1; 43511b41d2SMark Murray options->check_mail = -1; 44511b41d2SMark Murray options->x11_forwarding = -1; 45511b41d2SMark Murray options->x11_display_offset = -1; 46c2d3a559SKris Kennaway options->xauth_location = NULL; 47511b41d2SMark Murray options->strict_modes = -1; 48511b41d2SMark Murray options->keepalives = -1; 49511b41d2SMark Murray options->log_facility = (SyslogFacility) - 1; 50511b41d2SMark Murray options->log_level = (LogLevel) - 1; 51511b41d2SMark Murray options->rhosts_authentication = -1; 52511b41d2SMark Murray options->rhosts_rsa_authentication = -1; 53511b41d2SMark Murray options->rsa_authentication = -1; 54e8aafc91SKris Kennaway options->dsa_authentication = -1; 55511b41d2SMark Murray #ifdef KRB4 56fe5fd017SMark Murray options->krb4_authentication = -1; 57fe5fd017SMark Murray options->krb4_or_local_passwd = -1; 58fe5fd017SMark Murray options->krb4_ticket_cleanup = -1; 59511b41d2SMark Murray #endif 60fe5fd017SMark Murray #ifdef KRB5 61fe5fd017SMark Murray options->krb5_authentication = -1; 62fe5fd017SMark Murray options->krb5_tgt_passing = -1; 63fe5fd017SMark Murray #endif /* KRB5 */ 64511b41d2SMark Murray #ifdef AFS 65fe5fd017SMark Murray options->krb4_tgt_passing = -1; 66511b41d2SMark Murray options->afs_token_passing = -1; 67511b41d2SMark Murray #endif 68511b41d2SMark Murray options->password_authentication = -1; 6909958426SBrian Feldman options->kbd_interactive_authentication = -1; 70511b41d2SMark Murray #ifdef SKEY 71511b41d2SMark Murray options->skey_authentication = -1; 72511b41d2SMark Murray #endif 73511b41d2SMark Murray options->permit_empty_passwd = -1; 74511b41d2SMark Murray options->use_login = -1; 7509958426SBrian Feldman options->allow_tcp_forwarding = -1; 76511b41d2SMark Murray options->num_allow_users = 0; 77511b41d2SMark Murray options->num_deny_users = 0; 78511b41d2SMark Murray options->num_allow_groups = 0; 79511b41d2SMark Murray options->num_deny_groups = 0; 80e8aafc91SKris Kennaway options->ciphers = NULL; 81e8aafc91SKris Kennaway options->protocol = SSH_PROTO_UNKNOWN; 82e8aafc91SKris Kennaway options->gateway_ports = -1; 8342f71286SMark Murray options->connections_per_period = 0; 8442f71286SMark Murray options->connections_period = 0; 85c2d3a559SKris Kennaway options->num_subsystems = 0; 86c2d3a559SKris Kennaway options->max_startups_begin = -1; 87c2d3a559SKris Kennaway options->max_startups_rate = -1; 88c2d3a559SKris Kennaway options->max_startups = -1; 89511b41d2SMark Murray } 90511b41d2SMark Murray 91511b41d2SMark Murray void 92511b41d2SMark Murray fill_default_server_options(ServerOptions *options) 93511b41d2SMark Murray { 94511b41d2SMark Murray if (options->num_ports == 0) 95511b41d2SMark Murray options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 96511b41d2SMark Murray if (options->listen_addrs == NULL) 97511b41d2SMark Murray add_listen_addr(options, NULL); 98511b41d2SMark Murray if (options->host_key_file == NULL) 99511b41d2SMark Murray options->host_key_file = HOST_KEY_FILE; 100e8aafc91SKris Kennaway if (options->host_dsa_key_file == NULL) 101e8aafc91SKris Kennaway options->host_dsa_key_file = HOST_DSA_KEY_FILE; 102e8aafc91SKris Kennaway if (options->pid_file == NULL) 103e8aafc91SKris Kennaway options->pid_file = SSH_DAEMON_PID_FILE; 104511b41d2SMark Murray if (options->server_key_bits == -1) 105511b41d2SMark Murray options->server_key_bits = 768; 106511b41d2SMark Murray if (options->login_grace_time == -1) 107b87db7ceSKris Kennaway options->login_grace_time = 120; 108511b41d2SMark Murray if (options->key_regeneration_time == -1) 109511b41d2SMark Murray options->key_regeneration_time = 3600; 110511b41d2SMark Murray if (options->permit_root_login == -1) 111e213d985SPeter Wemm options->permit_root_login = 0; /* no */ 112511b41d2SMark Murray if (options->ignore_rhosts == -1) 113fe5fd017SMark Murray options->ignore_rhosts = 1; 114511b41d2SMark Murray if (options->ignore_user_known_hosts == -1) 115511b41d2SMark Murray options->ignore_user_known_hosts = 0; 116511b41d2SMark Murray if (options->check_mail == -1) 117365c420eSPeter Wemm options->check_mail = 1; 118511b41d2SMark Murray if (options->print_motd == -1) 119511b41d2SMark Murray options->print_motd = 1; 120511b41d2SMark Murray if (options->x11_forwarding == -1) 1211610cd7fSKris Kennaway options->x11_forwarding = 1; 122511b41d2SMark Murray if (options->x11_display_offset == -1) 123fe5fd017SMark Murray options->x11_display_offset = 10; 124c2d3a559SKris Kennaway #ifdef XAUTH_PATH 125c2d3a559SKris Kennaway if (options->xauth_location == NULL) 126c2d3a559SKris Kennaway options->xauth_location = XAUTH_PATH; 127c2d3a559SKris Kennaway #endif /* XAUTH_PATH */ 128511b41d2SMark Murray if (options->strict_modes == -1) 129511b41d2SMark Murray options->strict_modes = 1; 130511b41d2SMark Murray if (options->keepalives == -1) 131511b41d2SMark Murray options->keepalives = 1; 132511b41d2SMark Murray if (options->log_facility == (SyslogFacility) (-1)) 133511b41d2SMark Murray options->log_facility = SYSLOG_FACILITY_AUTH; 134511b41d2SMark Murray if (options->log_level == (LogLevel) (-1)) 135511b41d2SMark Murray options->log_level = SYSLOG_LEVEL_INFO; 136511b41d2SMark Murray if (options->rhosts_authentication == -1) 137511b41d2SMark Murray options->rhosts_authentication = 0; 138511b41d2SMark Murray if (options->rhosts_rsa_authentication == -1) 139fe5fd017SMark Murray options->rhosts_rsa_authentication = 0; 140511b41d2SMark Murray if (options->rsa_authentication == -1) 141511b41d2SMark Murray options->rsa_authentication = 1; 142e8aafc91SKris Kennaway if (options->dsa_authentication == -1) 143e8aafc91SKris Kennaway options->dsa_authentication = 1; 144511b41d2SMark Murray #ifdef KRB4 145fe5fd017SMark Murray if (options->krb4_authentication == -1) 146fe5fd017SMark Murray options->krb4_authentication = (access(KEYFILE, R_OK) == 0); 147fe5fd017SMark Murray if (options->krb4_or_local_passwd == -1) 148fe5fd017SMark Murray options->krb4_or_local_passwd = 1; 149fe5fd017SMark Murray if (options->krb4_ticket_cleanup == -1) 150fe5fd017SMark Murray options->krb4_ticket_cleanup = 1; 151511b41d2SMark Murray #endif /* KRB4 */ 152fe5fd017SMark Murray #ifdef KRB5 153fe5fd017SMark Murray if (options->krb5_authentication == -1) 154fe5fd017SMark Murray options->krb5_authentication = 1; 155fe5fd017SMark Murray if (options->krb5_tgt_passing == -1) 156fe5fd017SMark Murray options->krb5_tgt_passing = 1; 157fe5fd017SMark Murray #endif /* KRB5 */ 158511b41d2SMark Murray #ifdef AFS 159fe5fd017SMark Murray if (options->krb4_tgt_passing == -1) 160fe5fd017SMark Murray options->krb4_tgt_passing = 0; 161511b41d2SMark Murray if (options->afs_token_passing == -1) 162511b41d2SMark Murray options->afs_token_passing = k_hasafs(); 163511b41d2SMark Murray #endif /* AFS */ 164511b41d2SMark Murray if (options->password_authentication == -1) 165511b41d2SMark Murray options->password_authentication = 1; 16609958426SBrian Feldman if (options->kbd_interactive_authentication == -1) 16709958426SBrian Feldman options->kbd_interactive_authentication = 0; 168511b41d2SMark Murray #ifdef SKEY 169511b41d2SMark Murray if (options->skey_authentication == -1) 170511b41d2SMark Murray options->skey_authentication = 1; 171511b41d2SMark Murray #endif 172511b41d2SMark Murray if (options->permit_empty_passwd == -1) 173fe5fd017SMark Murray options->permit_empty_passwd = 0; 174511b41d2SMark Murray if (options->use_login == -1) 175511b41d2SMark Murray options->use_login = 0; 17609958426SBrian Feldman if (options->allow_tcp_forwarding == -1) 17709958426SBrian Feldman options->allow_tcp_forwarding = 1; 178e8aafc91SKris Kennaway if (options->protocol == SSH_PROTO_UNKNOWN) 179e8aafc91SKris Kennaway options->protocol = SSH_PROTO_1|SSH_PROTO_2; 180e8aafc91SKris Kennaway if (options->gateway_ports == -1) 181e8aafc91SKris Kennaway options->gateway_ports = 0; 182c2d3a559SKris Kennaway if (options->max_startups == -1) 183c2d3a559SKris Kennaway options->max_startups = 10; 184c2d3a559SKris Kennaway if (options->max_startups_rate == -1) 185c2d3a559SKris Kennaway options->max_startups_rate = 100; /* 100% */ 186c2d3a559SKris Kennaway if (options->max_startups_begin == -1) 187c2d3a559SKris Kennaway options->max_startups_begin = options->max_startups; 188511b41d2SMark Murray } 189511b41d2SMark Murray 190511b41d2SMark Murray /* Keyword tokens. */ 191511b41d2SMark Murray typedef enum { 192511b41d2SMark Murray sBadOption, /* == unknown option */ 193511b41d2SMark Murray sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, 194511b41d2SMark Murray sPermitRootLogin, sLogFacility, sLogLevel, 195511b41d2SMark Murray sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, 196511b41d2SMark Murray #ifdef KRB4 197fe5fd017SMark Murray sKrb4Authentication, sKrb4OrLocalPasswd, sKrb4TicketCleanup, 198511b41d2SMark Murray #endif 199fe5fd017SMark Murray #ifdef KRB5 200fe5fd017SMark Murray sKrb5Authentication, sKrb5TgtPassing, 201fe5fd017SMark Murray #endif /* KRB5 */ 202511b41d2SMark Murray #ifdef AFS 203fe5fd017SMark Murray sKrb4TgtPassing, sAFSTokenPassing, 204511b41d2SMark Murray #endif 205511b41d2SMark Murray #ifdef SKEY 206511b41d2SMark Murray sSkeyAuthentication, 207511b41d2SMark Murray #endif 20809958426SBrian Feldman sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, 209511b41d2SMark Murray sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, 210511b41d2SMark Murray sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, 21109958426SBrian Feldman sUseLogin, sAllowTcpForwarding, 21209958426SBrian Feldman sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 213e8aafc91SKris Kennaway sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, 214c2d3a559SKris Kennaway sGatewayPorts, sDSAAuthentication, sConnectionsPerPeriod, sXAuthLocation, 215c2d3a559SKris Kennaway sSubsystem, sMaxStartups 216511b41d2SMark Murray } ServerOpCodes; 217511b41d2SMark Murray 218511b41d2SMark Murray /* Textual representation of the tokens. */ 219511b41d2SMark Murray static struct { 220511b41d2SMark Murray const char *name; 221511b41d2SMark Murray ServerOpCodes opcode; 222511b41d2SMark Murray } keywords[] = { 223511b41d2SMark Murray { "port", sPort }, 224511b41d2SMark Murray { "hostkey", sHostKeyFile }, 225e8aafc91SKris Kennaway { "hostdsakey", sHostDSAKeyFile }, 226e8aafc91SKris Kennaway { "pidfile", sPidFile }, 227511b41d2SMark Murray { "serverkeybits", sServerKeyBits }, 228511b41d2SMark Murray { "logingracetime", sLoginGraceTime }, 229511b41d2SMark Murray { "keyregenerationinterval", sKeyRegenerationTime }, 230511b41d2SMark Murray { "permitrootlogin", sPermitRootLogin }, 231511b41d2SMark Murray { "syslogfacility", sLogFacility }, 232511b41d2SMark Murray { "loglevel", sLogLevel }, 233511b41d2SMark Murray { "rhostsauthentication", sRhostsAuthentication }, 234511b41d2SMark Murray { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 235511b41d2SMark Murray { "rsaauthentication", sRSAAuthentication }, 236e8aafc91SKris Kennaway { "dsaauthentication", sDSAAuthentication }, 237511b41d2SMark Murray #ifdef KRB4 238fe5fd017SMark Murray { "kerberos4authentication", sKrb4Authentication }, 239fe5fd017SMark Murray { "kerberos4orlocalpasswd", sKrb4OrLocalPasswd }, 240fe5fd017SMark Murray { "kerberos4ticketcleanup", sKrb4TicketCleanup }, 241511b41d2SMark Murray #endif 242fe5fd017SMark Murray #ifdef KRB5 243fe5fd017SMark Murray { "kerberos5authentication", sKrb5Authentication }, 244fe5fd017SMark Murray { "kerberos5tgtpassing", sKrb5TgtPassing }, 245fe5fd017SMark Murray #endif /* KRB5 */ 246511b41d2SMark Murray #ifdef AFS 247fe5fd017SMark Murray { "kerberos4tgtpassing", sKrb4TgtPassing }, 248511b41d2SMark Murray { "afstokenpassing", sAFSTokenPassing }, 249511b41d2SMark Murray #endif 250511b41d2SMark Murray { "passwordauthentication", sPasswordAuthentication }, 25109958426SBrian Feldman { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, 252511b41d2SMark Murray #ifdef SKEY 253511b41d2SMark Murray { "skeyauthentication", sSkeyAuthentication }, 254511b41d2SMark Murray #endif 255511b41d2SMark Murray { "checkmail", sCheckMail }, 256511b41d2SMark Murray { "listenaddress", sListenAddress }, 257511b41d2SMark Murray { "printmotd", sPrintMotd }, 258511b41d2SMark Murray { "ignorerhosts", sIgnoreRhosts }, 259511b41d2SMark Murray { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, 260511b41d2SMark Murray { "x11forwarding", sX11Forwarding }, 261511b41d2SMark Murray { "x11displayoffset", sX11DisplayOffset }, 262c2d3a559SKris Kennaway { "xauthlocation", sXAuthLocation }, 263511b41d2SMark Murray { "strictmodes", sStrictModes }, 264511b41d2SMark Murray { "permitemptypasswords", sEmptyPasswd }, 265511b41d2SMark Murray { "uselogin", sUseLogin }, 266511b41d2SMark Murray { "randomseed", sRandomSeedFile }, 267511b41d2SMark Murray { "keepalive", sKeepAlives }, 26809958426SBrian Feldman { "allowtcpforwarding", sAllowTcpForwarding }, 269511b41d2SMark Murray { "allowusers", sAllowUsers }, 270511b41d2SMark Murray { "denyusers", sDenyUsers }, 271511b41d2SMark Murray { "allowgroups", sAllowGroups }, 272511b41d2SMark Murray { "denygroups", sDenyGroups }, 273e8aafc91SKris Kennaway { "ciphers", sCiphers }, 274e8aafc91SKris Kennaway { "protocol", sProtocol }, 275e8aafc91SKris Kennaway { "gatewayports", sGatewayPorts }, 27642f71286SMark Murray { "connectionsperperiod", sConnectionsPerPeriod }, 277c2d3a559SKris Kennaway { "subsystem", sSubsystem }, 278c2d3a559SKris Kennaway { "maxstartups", sMaxStartups }, 279511b41d2SMark Murray { NULL, 0 } 280511b41d2SMark Murray }; 281511b41d2SMark Murray 282511b41d2SMark Murray /* 283511b41d2SMark Murray * Returns the number of the token pointed to by cp of length len. Never 284511b41d2SMark Murray * returns if the token is not known. 285511b41d2SMark Murray */ 286511b41d2SMark Murray 287511b41d2SMark Murray static ServerOpCodes 288511b41d2SMark Murray parse_token(const char *cp, const char *filename, 289511b41d2SMark Murray int linenum) 290511b41d2SMark Murray { 291511b41d2SMark Murray unsigned int i; 292511b41d2SMark Murray 293511b41d2SMark Murray for (i = 0; keywords[i].name; i++) 294511b41d2SMark Murray if (strcasecmp(cp, keywords[i].name) == 0) 295511b41d2SMark Murray return keywords[i].opcode; 296511b41d2SMark Murray 297511b41d2SMark Murray fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", 298511b41d2SMark Murray filename, linenum, cp); 299511b41d2SMark Murray return sBadOption; 300511b41d2SMark Murray } 301511b41d2SMark Murray 302511b41d2SMark Murray /* 303511b41d2SMark Murray * add listen address 304511b41d2SMark Murray */ 305511b41d2SMark Murray void 306511b41d2SMark Murray add_listen_addr(ServerOptions *options, char *addr) 307511b41d2SMark Murray { 308511b41d2SMark Murray extern int IPv4or6; 309511b41d2SMark Murray struct addrinfo hints, *ai, *aitop; 310511b41d2SMark Murray char strport[NI_MAXSERV]; 311511b41d2SMark Murray int gaierr; 312511b41d2SMark Murray int i; 313511b41d2SMark Murray 314511b41d2SMark Murray if (options->num_ports == 0) 315511b41d2SMark Murray options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 316511b41d2SMark Murray for (i = 0; i < options->num_ports; i++) { 317511b41d2SMark Murray memset(&hints, 0, sizeof(hints)); 318511b41d2SMark Murray hints.ai_family = IPv4or6; 319511b41d2SMark Murray hints.ai_socktype = SOCK_STREAM; 320511b41d2SMark Murray hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 321511b41d2SMark Murray snprintf(strport, sizeof strport, "%d", options->ports[i]); 322511b41d2SMark Murray if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 323511b41d2SMark Murray fatal("bad addr or host: %s (%s)\n", 324511b41d2SMark Murray addr ? addr : "<NULL>", 325511b41d2SMark Murray gai_strerror(gaierr)); 326511b41d2SMark Murray for (ai = aitop; ai->ai_next; ai = ai->ai_next) 327511b41d2SMark Murray ; 328511b41d2SMark Murray ai->ai_next = options->listen_addrs; 329511b41d2SMark Murray options->listen_addrs = aitop; 330511b41d2SMark Murray } 331511b41d2SMark Murray } 332511b41d2SMark Murray 333511b41d2SMark Murray /* Reads the server configuration file. */ 334511b41d2SMark Murray 335511b41d2SMark Murray void 336511b41d2SMark Murray read_server_config(ServerOptions *options, const char *filename) 337511b41d2SMark Murray { 338511b41d2SMark Murray FILE *f; 339511b41d2SMark Murray char line[1024]; 340c2d3a559SKris Kennaway char *cp, **charptr, *arg; 341511b41d2SMark Murray int linenum, *intptr, value; 342511b41d2SMark Murray int bad_options = 0; 343511b41d2SMark Murray ServerOpCodes opcode; 344c2d3a559SKris Kennaway int i; 345511b41d2SMark Murray 346511b41d2SMark Murray f = fopen(filename, "r"); 347511b41d2SMark Murray if (!f) { 348511b41d2SMark Murray perror(filename); 349511b41d2SMark Murray exit(1); 350511b41d2SMark Murray } 351511b41d2SMark Murray linenum = 0; 352511b41d2SMark Murray while (fgets(line, sizeof(line), f)) { 353511b41d2SMark Murray linenum++; 354c2d3a559SKris Kennaway cp = line; 355c2d3a559SKris Kennaway arg = strdelim(&cp); 356c2d3a559SKris Kennaway /* Ignore leading whitespace */ 357c2d3a559SKris Kennaway if (*arg == '\0') 358c2d3a559SKris Kennaway arg = strdelim(&cp); 359c2d3a559SKris Kennaway if (!*arg || *arg == '#') 360511b41d2SMark Murray continue; 361c2d3a559SKris Kennaway opcode = parse_token(arg, filename, linenum); 362511b41d2SMark Murray switch (opcode) { 363511b41d2SMark Murray case sBadOption: 364511b41d2SMark Murray bad_options++; 365511b41d2SMark Murray continue; 366511b41d2SMark Murray case sPort: 367511b41d2SMark Murray /* ignore ports from configfile if cmdline specifies ports */ 368511b41d2SMark Murray if (options->ports_from_cmdline) 369511b41d2SMark Murray continue; 370511b41d2SMark Murray if (options->listen_addrs != NULL) 371511b41d2SMark Murray fatal("%s line %d: ports must be specified before " 372511b41d2SMark Murray "ListenAdress.\n", filename, linenum); 373511b41d2SMark Murray if (options->num_ports >= MAX_PORTS) 374511b41d2SMark Murray fatal("%s line %d: too many ports.\n", 375511b41d2SMark Murray filename, linenum); 376c2d3a559SKris Kennaway arg = strdelim(&cp); 377c2d3a559SKris Kennaway if (!arg || *arg == '\0') 378511b41d2SMark Murray fatal("%s line %d: missing port number.\n", 379511b41d2SMark Murray filename, linenum); 380c2d3a559SKris Kennaway options->ports[options->num_ports++] = atoi(arg); 381511b41d2SMark Murray break; 382511b41d2SMark Murray 383511b41d2SMark Murray case sServerKeyBits: 384511b41d2SMark Murray intptr = &options->server_key_bits; 385511b41d2SMark Murray parse_int: 386c2d3a559SKris Kennaway arg = strdelim(&cp); 387c2d3a559SKris Kennaway if (!arg || *arg == '\0') { 388511b41d2SMark Murray fprintf(stderr, "%s line %d: missing integer value.\n", 389511b41d2SMark Murray filename, linenum); 390511b41d2SMark Murray exit(1); 391511b41d2SMark Murray } 392c2d3a559SKris Kennaway value = atoi(arg); 393c2d3a559SKris Kennaway if (value == 0) { 39442f71286SMark Murray fprintf(stderr, "%s line %d: invalid integer value.\n", 39542f71286SMark Murray filename, linenum); 39642f71286SMark Murray exit(1); 39742f71286SMark Murray } 398511b41d2SMark Murray if (*intptr == -1) 399511b41d2SMark Murray *intptr = value; 400511b41d2SMark Murray break; 401511b41d2SMark Murray 402511b41d2SMark Murray case sLoginGraceTime: 403511b41d2SMark Murray intptr = &options->login_grace_time; 404511b41d2SMark Murray goto parse_int; 405511b41d2SMark Murray 406511b41d2SMark Murray case sKeyRegenerationTime: 407511b41d2SMark Murray intptr = &options->key_regeneration_time; 408511b41d2SMark Murray goto parse_int; 409511b41d2SMark Murray 410511b41d2SMark Murray case sListenAddress: 411c2d3a559SKris Kennaway arg = strdelim(&cp); 412c2d3a559SKris Kennaway if (!arg || *arg == '\0') 413511b41d2SMark Murray fatal("%s line %d: missing inet addr.\n", 414511b41d2SMark Murray filename, linenum); 415c2d3a559SKris Kennaway add_listen_addr(options, arg); 416511b41d2SMark Murray break; 417511b41d2SMark Murray 418511b41d2SMark Murray case sHostKeyFile: 419e8aafc91SKris Kennaway case sHostDSAKeyFile: 420e8aafc91SKris Kennaway charptr = (opcode == sHostKeyFile ) ? 421e8aafc91SKris Kennaway &options->host_key_file : &options->host_dsa_key_file; 422c2d3a559SKris Kennaway parse_filename: 423c2d3a559SKris Kennaway arg = strdelim(&cp); 424c2d3a559SKris Kennaway if (!arg || *arg == '\0') { 425e8aafc91SKris Kennaway fprintf(stderr, "%s line %d: missing file name.\n", 426e8aafc91SKris Kennaway filename, linenum); 427e8aafc91SKris Kennaway exit(1); 428e8aafc91SKris Kennaway } 429e8aafc91SKris Kennaway if (*charptr == NULL) 430c2d3a559SKris Kennaway *charptr = tilde_expand_filename(arg, getuid()); 431e8aafc91SKris Kennaway break; 432e8aafc91SKris Kennaway 433e8aafc91SKris Kennaway case sPidFile: 434e8aafc91SKris Kennaway charptr = &options->pid_file; 435c2d3a559SKris Kennaway goto parse_filename; 436511b41d2SMark Murray 437511b41d2SMark Murray case sRandomSeedFile: 438511b41d2SMark Murray fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", 439511b41d2SMark Murray filename, linenum); 440c2d3a559SKris Kennaway arg = strdelim(&cp); 441511b41d2SMark Murray break; 442511b41d2SMark Murray 443511b41d2SMark Murray case sPermitRootLogin: 444511b41d2SMark Murray intptr = &options->permit_root_login; 445c2d3a559SKris Kennaway arg = strdelim(&cp); 446c2d3a559SKris Kennaway if (!arg || *arg == '\0') { 447511b41d2SMark Murray fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", 448511b41d2SMark Murray filename, linenum); 449511b41d2SMark Murray exit(1); 450511b41d2SMark Murray } 451c2d3a559SKris Kennaway if (strcmp(arg, "without-password") == 0) 452511b41d2SMark Murray value = 2; 453c2d3a559SKris Kennaway else if (strcmp(arg, "yes") == 0) 454511b41d2SMark Murray value = 1; 455c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0) 456511b41d2SMark Murray value = 0; 457511b41d2SMark Murray else { 458511b41d2SMark Murray fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", 459c2d3a559SKris Kennaway filename, linenum, arg); 460511b41d2SMark Murray exit(1); 461511b41d2SMark Murray } 462511b41d2SMark Murray if (*intptr == -1) 463511b41d2SMark Murray *intptr = value; 464511b41d2SMark Murray break; 465511b41d2SMark Murray 466511b41d2SMark Murray case sIgnoreRhosts: 467511b41d2SMark Murray intptr = &options->ignore_rhosts; 468511b41d2SMark Murray parse_flag: 469c2d3a559SKris Kennaway arg = strdelim(&cp); 470c2d3a559SKris Kennaway if (!arg || *arg == '\0') { 471511b41d2SMark Murray fprintf(stderr, "%s line %d: missing yes/no argument.\n", 472511b41d2SMark Murray filename, linenum); 473511b41d2SMark Murray exit(1); 474511b41d2SMark Murray } 475c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0) 476511b41d2SMark Murray value = 1; 477c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0) 478511b41d2SMark Murray value = 0; 479511b41d2SMark Murray else { 480511b41d2SMark Murray fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", 481c2d3a559SKris Kennaway filename, linenum, arg); 482511b41d2SMark Murray exit(1); 483511b41d2SMark Murray } 484511b41d2SMark Murray if (*intptr == -1) 485511b41d2SMark Murray *intptr = value; 486511b41d2SMark Murray break; 487511b41d2SMark Murray 488511b41d2SMark Murray case sIgnoreUserKnownHosts: 489511b41d2SMark Murray intptr = &options->ignore_user_known_hosts; 490962a3f4eSSheldon Hearn goto parse_flag; 491511b41d2SMark Murray 492511b41d2SMark Murray case sRhostsAuthentication: 493511b41d2SMark Murray intptr = &options->rhosts_authentication; 494511b41d2SMark Murray goto parse_flag; 495511b41d2SMark Murray 496511b41d2SMark Murray case sRhostsRSAAuthentication: 497511b41d2SMark Murray intptr = &options->rhosts_rsa_authentication; 498511b41d2SMark Murray goto parse_flag; 499511b41d2SMark Murray 500511b41d2SMark Murray case sRSAAuthentication: 501511b41d2SMark Murray intptr = &options->rsa_authentication; 502511b41d2SMark Murray goto parse_flag; 503511b41d2SMark Murray 504e8aafc91SKris Kennaway case sDSAAuthentication: 505e8aafc91SKris Kennaway intptr = &options->dsa_authentication; 506e8aafc91SKris Kennaway goto parse_flag; 507e8aafc91SKris Kennaway 508511b41d2SMark Murray #ifdef KRB4 509fe5fd017SMark Murray case sKrb4Authentication: 510fe5fd017SMark Murray intptr = &options->krb4_authentication; 511511b41d2SMark Murray goto parse_flag; 512511b41d2SMark Murray 513fe5fd017SMark Murray case sKrb4OrLocalPasswd: 514fe5fd017SMark Murray intptr = &options->krb4_or_local_passwd; 515511b41d2SMark Murray goto parse_flag; 516511b41d2SMark Murray 517fe5fd017SMark Murray case sKrb4TicketCleanup: 518fe5fd017SMark Murray intptr = &options->krb4_ticket_cleanup; 519511b41d2SMark Murray goto parse_flag; 520511b41d2SMark Murray #endif 521511b41d2SMark Murray 522fe5fd017SMark Murray #ifdef KRB5 523fe5fd017SMark Murray case sKrb5Authentication: 524fe5fd017SMark Murray intptr = &options->krb5_authentication; 525fe5fd017SMark Murray goto parse_flag; 526fe5fd017SMark Murray 527fe5fd017SMark Murray case sKrb5TgtPassing: 528fe5fd017SMark Murray intptr = &options->krb5_tgt_passing; 529fe5fd017SMark Murray goto parse_flag; 530fe5fd017SMark Murray #endif /* KRB5 */ 531fe5fd017SMark Murray 532511b41d2SMark Murray #ifdef AFS 533fe5fd017SMark Murray case sKrb4TgtPassing: 534fe5fd017SMark Murray intptr = &options->krb4_tgt_passing; 535511b41d2SMark Murray goto parse_flag; 536511b41d2SMark Murray 537511b41d2SMark Murray case sAFSTokenPassing: 538511b41d2SMark Murray intptr = &options->afs_token_passing; 539511b41d2SMark Murray goto parse_flag; 540511b41d2SMark Murray #endif 541511b41d2SMark Murray 542511b41d2SMark Murray case sPasswordAuthentication: 543511b41d2SMark Murray intptr = &options->password_authentication; 544511b41d2SMark Murray goto parse_flag; 545511b41d2SMark Murray 54609958426SBrian Feldman case sKbdInteractiveAuthentication: 54709958426SBrian Feldman intptr = &options->kbd_interactive_authentication; 54809958426SBrian Feldman goto parse_flag; 54909958426SBrian Feldman 550511b41d2SMark Murray case sCheckMail: 551511b41d2SMark Murray intptr = &options->check_mail; 552511b41d2SMark Murray goto parse_flag; 553511b41d2SMark Murray 554511b41d2SMark Murray #ifdef SKEY 555511b41d2SMark Murray case sSkeyAuthentication: 556511b41d2SMark Murray intptr = &options->skey_authentication; 557511b41d2SMark Murray goto parse_flag; 558511b41d2SMark Murray #endif 559511b41d2SMark Murray 560511b41d2SMark Murray case sPrintMotd: 561511b41d2SMark Murray intptr = &options->print_motd; 562511b41d2SMark Murray goto parse_flag; 563511b41d2SMark Murray 564511b41d2SMark Murray case sX11Forwarding: 565511b41d2SMark Murray intptr = &options->x11_forwarding; 566511b41d2SMark Murray goto parse_flag; 567511b41d2SMark Murray 568511b41d2SMark Murray case sX11DisplayOffset: 569511b41d2SMark Murray intptr = &options->x11_display_offset; 570511b41d2SMark Murray goto parse_int; 571511b41d2SMark Murray 572c2d3a559SKris Kennaway case sXAuthLocation: 573c2d3a559SKris Kennaway charptr = &options->xauth_location; 574c2d3a559SKris Kennaway goto parse_filename; 575c2d3a559SKris Kennaway 576511b41d2SMark Murray case sStrictModes: 577511b41d2SMark Murray intptr = &options->strict_modes; 578511b41d2SMark Murray goto parse_flag; 579511b41d2SMark Murray 580511b41d2SMark Murray case sKeepAlives: 581511b41d2SMark Murray intptr = &options->keepalives; 582511b41d2SMark Murray goto parse_flag; 583511b41d2SMark Murray 584511b41d2SMark Murray case sEmptyPasswd: 585511b41d2SMark Murray intptr = &options->permit_empty_passwd; 586511b41d2SMark Murray goto parse_flag; 587511b41d2SMark Murray 588511b41d2SMark Murray case sUseLogin: 589511b41d2SMark Murray intptr = &options->use_login; 590511b41d2SMark Murray goto parse_flag; 591511b41d2SMark Murray 592e8aafc91SKris Kennaway case sGatewayPorts: 593e8aafc91SKris Kennaway intptr = &options->gateway_ports; 594e8aafc91SKris Kennaway goto parse_flag; 595e8aafc91SKris Kennaway 596511b41d2SMark Murray case sLogFacility: 597511b41d2SMark Murray intptr = (int *) &options->log_facility; 598c2d3a559SKris Kennaway arg = strdelim(&cp); 599c2d3a559SKris Kennaway value = log_facility_number(arg); 600511b41d2SMark Murray if (value == (SyslogFacility) - 1) 601511b41d2SMark Murray fatal("%.200s line %d: unsupported log facility '%s'\n", 602c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 603511b41d2SMark Murray if (*intptr == -1) 604511b41d2SMark Murray *intptr = (SyslogFacility) value; 605511b41d2SMark Murray break; 606511b41d2SMark Murray 607511b41d2SMark Murray case sLogLevel: 608511b41d2SMark Murray intptr = (int *) &options->log_level; 609c2d3a559SKris Kennaway arg = strdelim(&cp); 610c2d3a559SKris Kennaway value = log_level_number(arg); 611511b41d2SMark Murray if (value == (LogLevel) - 1) 612511b41d2SMark Murray fatal("%.200s line %d: unsupported log level '%s'\n", 613c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 614511b41d2SMark Murray if (*intptr == -1) 615511b41d2SMark Murray *intptr = (LogLevel) value; 616511b41d2SMark Murray break; 617511b41d2SMark Murray 61809958426SBrian Feldman case sAllowTcpForwarding: 61909958426SBrian Feldman intptr = &options->allow_tcp_forwarding; 62009958426SBrian Feldman goto parse_flag; 62109958426SBrian Feldman 622511b41d2SMark Murray case sAllowUsers: 623c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 62442f71286SMark Murray if (options->num_allow_users >= MAX_ALLOW_USERS) 625e8aafc91SKris Kennaway fatal("%.200s line %d: too many allow users.\n", 626e8aafc91SKris Kennaway filename, linenum); 627c2d3a559SKris Kennaway options->allow_users[options->num_allow_users++] = xstrdup(arg); 628511b41d2SMark Murray } 629511b41d2SMark Murray break; 630511b41d2SMark Murray 631511b41d2SMark Murray case sDenyUsers: 632c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 6332803b77eSBrian Feldman if (options->num_deny_users >= MAX_DENY_USERS) 634e8aafc91SKris Kennaway fatal("%.200s line %d: too many deny users.\n", 635e8aafc91SKris Kennaway filename, linenum); 636c2d3a559SKris Kennaway options->deny_users[options->num_deny_users++] = xstrdup(arg); 637511b41d2SMark Murray } 638511b41d2SMark Murray break; 639511b41d2SMark Murray 640511b41d2SMark Murray case sAllowGroups: 641c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 64242f71286SMark Murray if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 643e8aafc91SKris Kennaway fatal("%.200s line %d: too many allow groups.\n", 644e8aafc91SKris Kennaway filename, linenum); 645c2d3a559SKris Kennaway options->allow_groups[options->num_allow_groups++] = xstrdup(arg); 646511b41d2SMark Murray } 647511b41d2SMark Murray break; 648511b41d2SMark Murray 649511b41d2SMark Murray case sDenyGroups: 650c2d3a559SKris Kennaway while ((arg = strdelim(&cp)) && *arg != '\0') { 65142f71286SMark Murray if (options->num_deny_groups >= MAX_DENY_GROUPS) 652e8aafc91SKris Kennaway fatal("%.200s line %d: too many deny groups.\n", 653e8aafc91SKris Kennaway filename, linenum); 654c2d3a559SKris Kennaway options->deny_groups[options->num_deny_groups++] = xstrdup(arg); 655511b41d2SMark Murray } 656511b41d2SMark Murray break; 657511b41d2SMark Murray 658e8aafc91SKris Kennaway case sCiphers: 659c2d3a559SKris Kennaway arg = strdelim(&cp); 660c2d3a559SKris Kennaway if (!arg || *arg == '\0') 661c322fe35SKris Kennaway fatal("%s line %d: Missing argument.", filename, linenum); 662c2d3a559SKris Kennaway if (!ciphers_valid(arg)) 663e8aafc91SKris Kennaway fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 664c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 665e8aafc91SKris Kennaway if (options->ciphers == NULL) 666c2d3a559SKris Kennaway options->ciphers = xstrdup(arg); 667e8aafc91SKris Kennaway break; 668e8aafc91SKris Kennaway 669e8aafc91SKris Kennaway case sProtocol: 670e8aafc91SKris Kennaway intptr = &options->protocol; 671c2d3a559SKris Kennaway arg = strdelim(&cp); 672c2d3a559SKris Kennaway if (!arg || *arg == '\0') 673c322fe35SKris Kennaway fatal("%s line %d: Missing argument.", filename, linenum); 674c2d3a559SKris Kennaway value = proto_spec(arg); 675e8aafc91SKris Kennaway if (value == SSH_PROTO_UNKNOWN) 676e8aafc91SKris Kennaway fatal("%s line %d: Bad protocol spec '%s'.", 677c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 678e8aafc91SKris Kennaway if (*intptr == SSH_PROTO_UNKNOWN) 679e8aafc91SKris Kennaway *intptr = value; 680e8aafc91SKris Kennaway break; 681e8aafc91SKris Kennaway 68242f71286SMark Murray case sConnectionsPerPeriod: 683c2d3a559SKris Kennaway arg = strdelim(&cp); 68442f71286SMark Murray if (cp == NULL) 68542f71286SMark Murray fatal("%.200s line %d: missing (>= 0) number argument.\n", 686511b41d2SMark Murray filename, linenum); 687c2d3a559SKris Kennaway if (sscanf(arg, "%u/%u", &options->connections_per_period, 68842f71286SMark Murray &options->connections_period) != 2) 68942f71286SMark Murray fatal("%.200s line %d: invalid numerical argument(s).\n", 69042f71286SMark Murray filename, linenum); 69142f71286SMark Murray if (options->connections_per_period != 0 && 69242f71286SMark Murray options->connections_period == 0) 69342f71286SMark Murray fatal("%.200s line %d: invalid connections period.\n", 69442f71286SMark Murray filename, linenum); 69542f71286SMark Murray break; 69642f71286SMark Murray 697c2d3a559SKris Kennaway case sSubsystem: 698c2d3a559SKris Kennaway if(options->num_subsystems >= MAX_SUBSYSTEMS) { 699c2d3a559SKris Kennaway fatal("%s line %d: too many subsystems defined.", 700c2d3a559SKris Kennaway filename, linenum); 701c2d3a559SKris Kennaway } 702c2d3a559SKris Kennaway arg = strdelim(&cp); 703c2d3a559SKris Kennaway if (!arg || *arg == '\0') 704c2d3a559SKris Kennaway fatal("%s line %d: Missing subsystem name.", 705c2d3a559SKris Kennaway filename, linenum); 706c2d3a559SKris Kennaway for (i = 0; i < options->num_subsystems; i++) 707c2d3a559SKris Kennaway if(strcmp(arg, options->subsystem_name[i]) == 0) 708c2d3a559SKris Kennaway fatal("%s line %d: Subsystem '%s' already defined.", 709c2d3a559SKris Kennaway filename, linenum, arg); 710c2d3a559SKris Kennaway options->subsystem_name[options->num_subsystems] = xstrdup(arg); 711c2d3a559SKris Kennaway arg = strdelim(&cp); 712c2d3a559SKris Kennaway if (!arg || *arg == '\0') 713c2d3a559SKris Kennaway fatal("%s line %d: Missing subsystem command.", 714c2d3a559SKris Kennaway filename, linenum); 715c2d3a559SKris Kennaway options->subsystem_command[options->num_subsystems] = xstrdup(arg); 716c2d3a559SKris Kennaway options->num_subsystems++; 717c2d3a559SKris Kennaway break; 718c2d3a559SKris Kennaway 719c2d3a559SKris Kennaway case sMaxStartups: 720c2d3a559SKris Kennaway arg = strdelim(&cp); 721c2d3a559SKris Kennaway if (!arg || *arg == '\0') 722c2d3a559SKris Kennaway fatal("%s line %d: Missing MaxStartups spec.", 723c2d3a559SKris Kennaway filename, linenum); 724c2d3a559SKris Kennaway if (sscanf(arg, "%d:%d:%d", 725c2d3a559SKris Kennaway &options->max_startups_begin, 726c2d3a559SKris Kennaway &options->max_startups_rate, 727c2d3a559SKris Kennaway &options->max_startups) == 3) { 728c2d3a559SKris Kennaway if (options->max_startups_begin > 729c2d3a559SKris Kennaway options->max_startups || 730c2d3a559SKris Kennaway options->max_startups_rate > 100 || 731c2d3a559SKris Kennaway options->max_startups_rate < 1) 732c2d3a559SKris Kennaway fatal("%s line %d: Illegal MaxStartups spec.", 733c2d3a559SKris Kennaway filename, linenum); 734c2d3a559SKris Kennaway break; 735c2d3a559SKris Kennaway } 736c2d3a559SKris Kennaway intptr = &options->max_startups; 737c2d3a559SKris Kennaway goto parse_int; 738c2d3a559SKris Kennaway 73942f71286SMark Murray default: 74042f71286SMark Murray fatal("%.200s line %d: Missing handler for opcode %s (%d)\n", 741c2d3a559SKris Kennaway filename, linenum,arg, opcode); 742511b41d2SMark Murray } 743c2d3a559SKris Kennaway if ((arg = strdelim(&cp)) != NULL && *arg != '\0') { 744c2d3a559SKris Kennaway fprintf(stderr, 745c2d3a559SKris Kennaway "%s line %d: garbage at end of line; \"%.200s\".\n", 746c2d3a559SKris Kennaway filename, linenum, arg); 747c2d3a559SKris Kennaway exit(1); 748e8aafc91SKris Kennaway } 749511b41d2SMark Murray } 750511b41d2SMark Murray fclose(f); 751e8aafc91SKris Kennaway if (bad_options > 0) { 75242f71286SMark Murray fatal("%.200s: terminating, %d bad configuration options\n", 753511b41d2SMark Murray filename, bad_options); 754511b41d2SMark Murray } 755e8aafc91SKris Kennaway } 756