1 /* 2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * All rights reserved 4 * 5 * As far as I am concerned, the code I have written for this software 6 * can be used freely for any purpose. Any derived versions of this 7 * software must be clearly marked as such, and if the derived work is 8 * incompatible with the protocol description in the RFC file, it must be 9 * called by a name other than "ssh" or "Secure Shell". 10 */ 11 12 #include "includes.h" 13 RCSID("$OpenBSD: servconf.c,v 1.51 2000/09/07 20:27:53 deraadt Exp $"); 14 RCSID("$FreeBSD$"); 15 16 #include "ssh.h" 17 #include "servconf.h" 18 #include "xmalloc.h" 19 #include "compat.h" 20 21 /* add listen address */ 22 void add_listen_addr(ServerOptions *options, char *addr); 23 24 /* Initializes the server options to their default values. */ 25 26 void 27 initialize_server_options(ServerOptions *options) 28 { 29 memset(options, 0, sizeof(*options)); 30 options->num_ports = 0; 31 options->ports_from_cmdline = 0; 32 options->listen_addrs = NULL; 33 options->host_key_file = NULL; 34 options->host_dsa_key_file = NULL; 35 options->pid_file = NULL; 36 options->server_key_bits = -1; 37 options->login_grace_time = -1; 38 options->key_regeneration_time = -1; 39 options->permit_root_login = -1; 40 options->ignore_rhosts = -1; 41 options->ignore_user_known_hosts = -1; 42 options->print_motd = -1; 43 options->check_mail = -1; 44 options->x11_forwarding = -1; 45 options->x11_display_offset = -1; 46 options->xauth_location = NULL; 47 options->strict_modes = -1; 48 options->keepalives = -1; 49 options->log_facility = (SyslogFacility) - 1; 50 options->log_level = (LogLevel) - 1; 51 options->rhosts_authentication = -1; 52 options->rhosts_rsa_authentication = -1; 53 options->rsa_authentication = -1; 54 options->dsa_authentication = -1; 55 #ifdef KRB4 56 options->krb4_authentication = -1; 57 options->krb4_or_local_passwd = -1; 58 options->krb4_ticket_cleanup = -1; 59 #endif 60 #ifdef KRB5 61 options->krb5_authentication = -1; 62 options->krb5_tgt_passing = -1; 63 #endif /* KRB5 */ 64 #ifdef AFS 65 options->krb4_tgt_passing = -1; 66 options->afs_token_passing = -1; 67 #endif 68 options->password_authentication = -1; 69 #ifdef SKEY 70 options->skey_authentication = -1; 71 #endif 72 options->permit_empty_passwd = -1; 73 options->use_login = -1; 74 options->num_allow_users = 0; 75 options->num_deny_users = 0; 76 options->num_allow_groups = 0; 77 options->num_deny_groups = 0; 78 options->ciphers = NULL; 79 options->protocol = SSH_PROTO_UNKNOWN; 80 options->gateway_ports = -1; 81 options->connections_per_period = 0; 82 options->connections_period = 0; 83 options->num_subsystems = 0; 84 options->max_startups_begin = -1; 85 options->max_startups_rate = -1; 86 options->max_startups = -1; 87 } 88 89 void 90 fill_default_server_options(ServerOptions *options) 91 { 92 if (options->num_ports == 0) 93 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 94 if (options->listen_addrs == NULL) 95 add_listen_addr(options, NULL); 96 if (options->host_key_file == NULL) 97 options->host_key_file = HOST_KEY_FILE; 98 if (options->host_dsa_key_file == NULL) 99 options->host_dsa_key_file = HOST_DSA_KEY_FILE; 100 if (options->pid_file == NULL) 101 options->pid_file = SSH_DAEMON_PID_FILE; 102 if (options->server_key_bits == -1) 103 options->server_key_bits = 768; 104 if (options->login_grace_time == -1) 105 options->login_grace_time = 120; 106 if (options->key_regeneration_time == -1) 107 options->key_regeneration_time = 3600; 108 if (options->permit_root_login == -1) 109 options->permit_root_login = 0; /* no */ 110 if (options->ignore_rhosts == -1) 111 options->ignore_rhosts = 1; 112 if (options->ignore_user_known_hosts == -1) 113 options->ignore_user_known_hosts = 0; 114 if (options->check_mail == -1) 115 options->check_mail = 1; 116 if (options->print_motd == -1) 117 options->print_motd = 1; 118 if (options->x11_forwarding == -1) 119 options->x11_forwarding = 1; 120 if (options->x11_display_offset == -1) 121 options->x11_display_offset = 10; 122 #ifdef XAUTH_PATH 123 if (options->xauth_location == NULL) 124 options->xauth_location = XAUTH_PATH; 125 #endif /* XAUTH_PATH */ 126 if (options->strict_modes == -1) 127 options->strict_modes = 1; 128 if (options->keepalives == -1) 129 options->keepalives = 1; 130 if (options->log_facility == (SyslogFacility) (-1)) 131 options->log_facility = SYSLOG_FACILITY_AUTH; 132 if (options->log_level == (LogLevel) (-1)) 133 options->log_level = SYSLOG_LEVEL_INFO; 134 if (options->rhosts_authentication == -1) 135 options->rhosts_authentication = 0; 136 if (options->rhosts_rsa_authentication == -1) 137 options->rhosts_rsa_authentication = 0; 138 if (options->rsa_authentication == -1) 139 options->rsa_authentication = 1; 140 if (options->dsa_authentication == -1) 141 options->dsa_authentication = 1; 142 #ifdef KRB4 143 if (options->krb4_authentication == -1) 144 options->krb4_authentication = (access(KEYFILE, R_OK) == 0); 145 if (options->krb4_or_local_passwd == -1) 146 options->krb4_or_local_passwd = 1; 147 if (options->krb4_ticket_cleanup == -1) 148 options->krb4_ticket_cleanup = 1; 149 #endif /* KRB4 */ 150 #ifdef KRB5 151 if (options->krb5_authentication == -1) 152 options->krb5_authentication = 1; 153 if (options->krb5_tgt_passing == -1) 154 options->krb5_tgt_passing = 1; 155 #endif /* KRB5 */ 156 #ifdef AFS 157 if (options->krb4_tgt_passing == -1) 158 options->krb4_tgt_passing = 0; 159 if (options->afs_token_passing == -1) 160 options->afs_token_passing = k_hasafs(); 161 #endif /* AFS */ 162 if (options->password_authentication == -1) 163 options->password_authentication = 1; 164 #ifdef SKEY 165 if (options->skey_authentication == -1) 166 options->skey_authentication = 1; 167 #endif 168 if (options->permit_empty_passwd == -1) 169 options->permit_empty_passwd = 0; 170 if (options->use_login == -1) 171 options->use_login = 0; 172 if (options->protocol == SSH_PROTO_UNKNOWN) 173 options->protocol = SSH_PROTO_1|SSH_PROTO_2; 174 if (options->gateway_ports == -1) 175 options->gateway_ports = 0; 176 if (options->max_startups == -1) 177 options->max_startups = 10; 178 if (options->max_startups_rate == -1) 179 options->max_startups_rate = 100; /* 100% */ 180 if (options->max_startups_begin == -1) 181 options->max_startups_begin = options->max_startups; 182 } 183 184 /* Keyword tokens. */ 185 typedef enum { 186 sBadOption, /* == unknown option */ 187 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, 188 sPermitRootLogin, sLogFacility, sLogLevel, 189 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, 190 #ifdef KRB4 191 sKrb4Authentication, sKrb4OrLocalPasswd, sKrb4TicketCleanup, 192 #endif 193 #ifdef KRB5 194 sKrb5Authentication, sKrb5TgtPassing, 195 #endif /* KRB5 */ 196 #ifdef AFS 197 sKrb4TgtPassing, sAFSTokenPassing, 198 #endif 199 #ifdef SKEY 200 sSkeyAuthentication, 201 #endif 202 sPasswordAuthentication, sListenAddress, 203 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, 204 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, 205 sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 206 sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, 207 sGatewayPorts, sDSAAuthentication, sConnectionsPerPeriod, sXAuthLocation, 208 sSubsystem, sMaxStartups 209 } ServerOpCodes; 210 211 /* Textual representation of the tokens. */ 212 static struct { 213 const char *name; 214 ServerOpCodes opcode; 215 } keywords[] = { 216 { "port", sPort }, 217 { "hostkey", sHostKeyFile }, 218 { "hostdsakey", sHostDSAKeyFile }, 219 { "pidfile", sPidFile }, 220 { "serverkeybits", sServerKeyBits }, 221 { "logingracetime", sLoginGraceTime }, 222 { "keyregenerationinterval", sKeyRegenerationTime }, 223 { "permitrootlogin", sPermitRootLogin }, 224 { "syslogfacility", sLogFacility }, 225 { "loglevel", sLogLevel }, 226 { "rhostsauthentication", sRhostsAuthentication }, 227 { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 228 { "rsaauthentication", sRSAAuthentication }, 229 { "dsaauthentication", sDSAAuthentication }, 230 #ifdef KRB4 231 { "kerberos4authentication", sKrb4Authentication }, 232 { "kerberos4orlocalpasswd", sKrb4OrLocalPasswd }, 233 { "kerberos4ticketcleanup", sKrb4TicketCleanup }, 234 #endif 235 #ifdef KRB5 236 { "kerberos5authentication", sKrb5Authentication }, 237 { "kerberos5tgtpassing", sKrb5TgtPassing }, 238 #endif /* KRB5 */ 239 #ifdef AFS 240 { "kerberos4tgtpassing", sKrb4TgtPassing }, 241 { "afstokenpassing", sAFSTokenPassing }, 242 #endif 243 { "passwordauthentication", sPasswordAuthentication }, 244 #ifdef SKEY 245 { "skeyauthentication", sSkeyAuthentication }, 246 #endif 247 { "checkmail", sCheckMail }, 248 { "listenaddress", sListenAddress }, 249 { "printmotd", sPrintMotd }, 250 { "ignorerhosts", sIgnoreRhosts }, 251 { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, 252 { "x11forwarding", sX11Forwarding }, 253 { "x11displayoffset", sX11DisplayOffset }, 254 { "xauthlocation", sXAuthLocation }, 255 { "strictmodes", sStrictModes }, 256 { "permitemptypasswords", sEmptyPasswd }, 257 { "uselogin", sUseLogin }, 258 { "randomseed", sRandomSeedFile }, 259 { "keepalive", sKeepAlives }, 260 { "allowusers", sAllowUsers }, 261 { "denyusers", sDenyUsers }, 262 { "allowgroups", sAllowGroups }, 263 { "denygroups", sDenyGroups }, 264 { "ciphers", sCiphers }, 265 { "protocol", sProtocol }, 266 { "gatewayports", sGatewayPorts }, 267 { "connectionsperperiod", sConnectionsPerPeriod }, 268 { "subsystem", sSubsystem }, 269 { "maxstartups", sMaxStartups }, 270 { NULL, 0 } 271 }; 272 273 /* 274 * Returns the number of the token pointed to by cp of length len. Never 275 * returns if the token is not known. 276 */ 277 278 static ServerOpCodes 279 parse_token(const char *cp, const char *filename, 280 int linenum) 281 { 282 unsigned int i; 283 284 for (i = 0; keywords[i].name; i++) 285 if (strcasecmp(cp, keywords[i].name) == 0) 286 return keywords[i].opcode; 287 288 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", 289 filename, linenum, cp); 290 return sBadOption; 291 } 292 293 /* 294 * add listen address 295 */ 296 void 297 add_listen_addr(ServerOptions *options, char *addr) 298 { 299 extern int IPv4or6; 300 struct addrinfo hints, *ai, *aitop; 301 char strport[NI_MAXSERV]; 302 int gaierr; 303 int i; 304 305 if (options->num_ports == 0) 306 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 307 for (i = 0; i < options->num_ports; i++) { 308 memset(&hints, 0, sizeof(hints)); 309 hints.ai_family = IPv4or6; 310 hints.ai_socktype = SOCK_STREAM; 311 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 312 snprintf(strport, sizeof strport, "%d", options->ports[i]); 313 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 314 fatal("bad addr or host: %s (%s)\n", 315 addr ? addr : "<NULL>", 316 gai_strerror(gaierr)); 317 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 318 ; 319 ai->ai_next = options->listen_addrs; 320 options->listen_addrs = aitop; 321 } 322 } 323 324 /* Reads the server configuration file. */ 325 326 void 327 read_server_config(ServerOptions *options, const char *filename) 328 { 329 FILE *f; 330 char line[1024]; 331 char *cp, **charptr, *arg; 332 int linenum, *intptr, value; 333 int bad_options = 0; 334 ServerOpCodes opcode; 335 int i; 336 337 f = fopen(filename, "r"); 338 if (!f) { 339 perror(filename); 340 exit(1); 341 } 342 linenum = 0; 343 while (fgets(line, sizeof(line), f)) { 344 linenum++; 345 cp = line; 346 arg = strdelim(&cp); 347 /* Ignore leading whitespace */ 348 if (*arg == '\0') 349 arg = strdelim(&cp); 350 if (!*arg || *arg == '#') 351 continue; 352 opcode = parse_token(arg, filename, linenum); 353 switch (opcode) { 354 case sBadOption: 355 bad_options++; 356 continue; 357 case sPort: 358 /* ignore ports from configfile if cmdline specifies ports */ 359 if (options->ports_from_cmdline) 360 continue; 361 if (options->listen_addrs != NULL) 362 fatal("%s line %d: ports must be specified before " 363 "ListenAdress.\n", filename, linenum); 364 if (options->num_ports >= MAX_PORTS) 365 fatal("%s line %d: too many ports.\n", 366 filename, linenum); 367 arg = strdelim(&cp); 368 if (!arg || *arg == '\0') 369 fatal("%s line %d: missing port number.\n", 370 filename, linenum); 371 options->ports[options->num_ports++] = atoi(arg); 372 break; 373 374 case sServerKeyBits: 375 intptr = &options->server_key_bits; 376 parse_int: 377 arg = strdelim(&cp); 378 if (!arg || *arg == '\0') { 379 fprintf(stderr, "%s line %d: missing integer value.\n", 380 filename, linenum); 381 exit(1); 382 } 383 value = atoi(arg); 384 if (value == 0) { 385 fprintf(stderr, "%s line %d: invalid integer value.\n", 386 filename, linenum); 387 exit(1); 388 } 389 if (*intptr == -1) 390 *intptr = value; 391 break; 392 393 case sLoginGraceTime: 394 intptr = &options->login_grace_time; 395 goto parse_int; 396 397 case sKeyRegenerationTime: 398 intptr = &options->key_regeneration_time; 399 goto parse_int; 400 401 case sListenAddress: 402 arg = strdelim(&cp); 403 if (!arg || *arg == '\0') 404 fatal("%s line %d: missing inet addr.\n", 405 filename, linenum); 406 add_listen_addr(options, arg); 407 break; 408 409 case sHostKeyFile: 410 case sHostDSAKeyFile: 411 charptr = (opcode == sHostKeyFile ) ? 412 &options->host_key_file : &options->host_dsa_key_file; 413 parse_filename: 414 arg = strdelim(&cp); 415 if (!arg || *arg == '\0') { 416 fprintf(stderr, "%s line %d: missing file name.\n", 417 filename, linenum); 418 exit(1); 419 } 420 if (*charptr == NULL) 421 *charptr = tilde_expand_filename(arg, getuid()); 422 break; 423 424 case sPidFile: 425 charptr = &options->pid_file; 426 goto parse_filename; 427 428 case sRandomSeedFile: 429 fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", 430 filename, linenum); 431 arg = strdelim(&cp); 432 break; 433 434 case sPermitRootLogin: 435 intptr = &options->permit_root_login; 436 arg = strdelim(&cp); 437 if (!arg || *arg == '\0') { 438 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", 439 filename, linenum); 440 exit(1); 441 } 442 if (strcmp(arg, "without-password") == 0) 443 value = 2; 444 else if (strcmp(arg, "yes") == 0) 445 value = 1; 446 else if (strcmp(arg, "no") == 0) 447 value = 0; 448 else { 449 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", 450 filename, linenum, arg); 451 exit(1); 452 } 453 if (*intptr == -1) 454 *intptr = value; 455 break; 456 457 case sIgnoreRhosts: 458 intptr = &options->ignore_rhosts; 459 parse_flag: 460 arg = strdelim(&cp); 461 if (!arg || *arg == '\0') { 462 fprintf(stderr, "%s line %d: missing yes/no argument.\n", 463 filename, linenum); 464 exit(1); 465 } 466 if (strcmp(arg, "yes") == 0) 467 value = 1; 468 else if (strcmp(arg, "no") == 0) 469 value = 0; 470 else { 471 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", 472 filename, linenum, arg); 473 exit(1); 474 } 475 if (*intptr == -1) 476 *intptr = value; 477 break; 478 479 case sIgnoreUserKnownHosts: 480 intptr = &options->ignore_user_known_hosts; 481 goto parse_flag; 482 483 case sRhostsAuthentication: 484 intptr = &options->rhosts_authentication; 485 goto parse_flag; 486 487 case sRhostsRSAAuthentication: 488 intptr = &options->rhosts_rsa_authentication; 489 goto parse_flag; 490 491 case sRSAAuthentication: 492 intptr = &options->rsa_authentication; 493 goto parse_flag; 494 495 case sDSAAuthentication: 496 intptr = &options->dsa_authentication; 497 goto parse_flag; 498 499 #ifdef KRB4 500 case sKrb4Authentication: 501 intptr = &options->krb4_authentication; 502 goto parse_flag; 503 504 case sKrb4OrLocalPasswd: 505 intptr = &options->krb4_or_local_passwd; 506 goto parse_flag; 507 508 case sKrb4TicketCleanup: 509 intptr = &options->krb4_ticket_cleanup; 510 goto parse_flag; 511 #endif 512 513 #ifdef KRB5 514 case sKrb5Authentication: 515 intptr = &options->krb5_authentication; 516 goto parse_flag; 517 518 case sKrb5TgtPassing: 519 intptr = &options->krb5_tgt_passing; 520 goto parse_flag; 521 #endif /* KRB5 */ 522 523 #ifdef AFS 524 case sKrb4TgtPassing: 525 intptr = &options->krb4_tgt_passing; 526 goto parse_flag; 527 528 case sAFSTokenPassing: 529 intptr = &options->afs_token_passing; 530 goto parse_flag; 531 #endif 532 533 case sPasswordAuthentication: 534 intptr = &options->password_authentication; 535 goto parse_flag; 536 537 case sCheckMail: 538 intptr = &options->check_mail; 539 goto parse_flag; 540 541 #ifdef SKEY 542 case sSkeyAuthentication: 543 intptr = &options->skey_authentication; 544 goto parse_flag; 545 #endif 546 547 case sPrintMotd: 548 intptr = &options->print_motd; 549 goto parse_flag; 550 551 case sX11Forwarding: 552 intptr = &options->x11_forwarding; 553 goto parse_flag; 554 555 case sX11DisplayOffset: 556 intptr = &options->x11_display_offset; 557 goto parse_int; 558 559 case sXAuthLocation: 560 charptr = &options->xauth_location; 561 goto parse_filename; 562 563 case sStrictModes: 564 intptr = &options->strict_modes; 565 goto parse_flag; 566 567 case sKeepAlives: 568 intptr = &options->keepalives; 569 goto parse_flag; 570 571 case sEmptyPasswd: 572 intptr = &options->permit_empty_passwd; 573 goto parse_flag; 574 575 case sUseLogin: 576 intptr = &options->use_login; 577 goto parse_flag; 578 579 case sGatewayPorts: 580 intptr = &options->gateway_ports; 581 goto parse_flag; 582 583 case sLogFacility: 584 intptr = (int *) &options->log_facility; 585 arg = strdelim(&cp); 586 value = log_facility_number(arg); 587 if (value == (SyslogFacility) - 1) 588 fatal("%.200s line %d: unsupported log facility '%s'\n", 589 filename, linenum, arg ? arg : "<NONE>"); 590 if (*intptr == -1) 591 *intptr = (SyslogFacility) value; 592 break; 593 594 case sLogLevel: 595 intptr = (int *) &options->log_level; 596 arg = strdelim(&cp); 597 value = log_level_number(arg); 598 if (value == (LogLevel) - 1) 599 fatal("%.200s line %d: unsupported log level '%s'\n", 600 filename, linenum, arg ? arg : "<NONE>"); 601 if (*intptr == -1) 602 *intptr = (LogLevel) value; 603 break; 604 605 case sAllowUsers: 606 while ((arg = strdelim(&cp)) && *arg != '\0') { 607 if (options->num_allow_users >= MAX_ALLOW_USERS) 608 fatal("%.200s line %d: too many allow users.\n", 609 filename, linenum); 610 options->allow_users[options->num_allow_users++] = xstrdup(arg); 611 } 612 break; 613 614 case sDenyUsers: 615 while ((arg = strdelim(&cp)) && *arg != '\0') { 616 if (options->num_deny_users >= MAX_DENY_USERS) 617 fatal("%.200s line %d: too many deny users.\n", 618 filename, linenum); 619 options->deny_users[options->num_deny_users++] = xstrdup(arg); 620 } 621 break; 622 623 case sAllowGroups: 624 while ((arg = strdelim(&cp)) && *arg != '\0') { 625 if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 626 fatal("%.200s line %d: too many allow groups.\n", 627 filename, linenum); 628 options->allow_groups[options->num_allow_groups++] = xstrdup(arg); 629 } 630 break; 631 632 case sDenyGroups: 633 while ((arg = strdelim(&cp)) && *arg != '\0') { 634 if (options->num_deny_groups >= MAX_DENY_GROUPS) 635 fatal("%.200s line %d: too many deny groups.\n", 636 filename, linenum); 637 options->deny_groups[options->num_deny_groups++] = xstrdup(arg); 638 } 639 break; 640 641 case sCiphers: 642 arg = strdelim(&cp); 643 if (!arg || *arg == '\0') 644 fatal("%s line %d: Missing argument.", filename, linenum); 645 if (!ciphers_valid(arg)) 646 fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 647 filename, linenum, arg ? arg : "<NONE>"); 648 if (options->ciphers == NULL) 649 options->ciphers = xstrdup(arg); 650 break; 651 652 case sProtocol: 653 intptr = &options->protocol; 654 arg = strdelim(&cp); 655 if (!arg || *arg == '\0') 656 fatal("%s line %d: Missing argument.", filename, linenum); 657 value = proto_spec(arg); 658 if (value == SSH_PROTO_UNKNOWN) 659 fatal("%s line %d: Bad protocol spec '%s'.", 660 filename, linenum, arg ? arg : "<NONE>"); 661 if (*intptr == SSH_PROTO_UNKNOWN) 662 *intptr = value; 663 break; 664 665 case sConnectionsPerPeriod: 666 arg = strdelim(&cp); 667 if (cp == NULL) 668 fatal("%.200s line %d: missing (>= 0) number argument.\n", 669 filename, linenum); 670 if (sscanf(arg, "%u/%u", &options->connections_per_period, 671 &options->connections_period) != 2) 672 fatal("%.200s line %d: invalid numerical argument(s).\n", 673 filename, linenum); 674 if (options->connections_per_period != 0 && 675 options->connections_period == 0) 676 fatal("%.200s line %d: invalid connections period.\n", 677 filename, linenum); 678 break; 679 680 case sSubsystem: 681 if(options->num_subsystems >= MAX_SUBSYSTEMS) { 682 fatal("%s line %d: too many subsystems defined.", 683 filename, linenum); 684 } 685 arg = strdelim(&cp); 686 if (!arg || *arg == '\0') 687 fatal("%s line %d: Missing subsystem name.", 688 filename, linenum); 689 for (i = 0; i < options->num_subsystems; i++) 690 if(strcmp(arg, options->subsystem_name[i]) == 0) 691 fatal("%s line %d: Subsystem '%s' already defined.", 692 filename, linenum, arg); 693 options->subsystem_name[options->num_subsystems] = xstrdup(arg); 694 arg = strdelim(&cp); 695 if (!arg || *arg == '\0') 696 fatal("%s line %d: Missing subsystem command.", 697 filename, linenum); 698 options->subsystem_command[options->num_subsystems] = xstrdup(arg); 699 options->num_subsystems++; 700 break; 701 702 case sMaxStartups: 703 arg = strdelim(&cp); 704 if (!arg || *arg == '\0') 705 fatal("%s line %d: Missing MaxStartups spec.", 706 filename, linenum); 707 if (sscanf(arg, "%d:%d:%d", 708 &options->max_startups_begin, 709 &options->max_startups_rate, 710 &options->max_startups) == 3) { 711 if (options->max_startups_begin > 712 options->max_startups || 713 options->max_startups_rate > 100 || 714 options->max_startups_rate < 1) 715 fatal("%s line %d: Illegal MaxStartups spec.", 716 filename, linenum); 717 break; 718 } 719 intptr = &options->max_startups; 720 goto parse_int; 721 722 default: 723 fatal("%.200s line %d: Missing handler for opcode %s (%d)\n", 724 filename, linenum,arg, opcode); 725 } 726 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') { 727 fprintf(stderr, 728 "%s line %d: garbage at end of line; \"%.200s\".\n", 729 filename, linenum, arg); 730 exit(1); 731 } 732 } 733 fclose(f); 734 if (bad_options > 0) { 735 fatal("%.200s: terminating, %d bad configuration options\n", 736 filename, bad_options); 737 } 738 } 739