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