diff options
Diffstat (limited to 'servconf.c')
-rw-r--r-- | servconf.c | 137 |
1 files changed, 73 insertions, 64 deletions
diff --git a/servconf.c b/servconf.c index 12cc15260..77ac84527 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$OpenBSD: servconf.c,v 1.45 2000/06/20 01:39:44 markus Exp $"); | 15 | RCSID("$OpenBSD: servconf.c,v 1.47 2000/07/10 16:30:25 ho Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "servconf.h" | 18 | #include "servconf.h" |
@@ -76,6 +76,7 @@ initialize_server_options(ServerOptions *options) | |||
76 | options->protocol = SSH_PROTO_UNKNOWN; | 76 | options->protocol = SSH_PROTO_UNKNOWN; |
77 | options->gateway_ports = -1; | 77 | options->gateway_ports = -1; |
78 | options->num_subsystems = 0; | 78 | options->num_subsystems = 0; |
79 | options->max_startups = -1; | ||
79 | } | 80 | } |
80 | 81 | ||
81 | void | 82 | void |
@@ -159,6 +160,8 @@ fill_default_server_options(ServerOptions *options) | |||
159 | options->protocol = SSH_PROTO_1|SSH_PROTO_2; | 160 | options->protocol = SSH_PROTO_1|SSH_PROTO_2; |
160 | if (options->gateway_ports == -1) | 161 | if (options->gateway_ports == -1) |
161 | options->gateway_ports = 0; | 162 | options->gateway_ports = 0; |
163 | if (options->max_startups == -1) | ||
164 | options->max_startups = 10; | ||
162 | } | 165 | } |
163 | 166 | ||
164 | #define WHITESPACE " \t\r\n=" | 167 | #define WHITESPACE " \t\r\n=" |
@@ -183,7 +186,7 @@ typedef enum { | |||
183 | sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, | 186 | sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, |
184 | sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, | 187 | sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, |
185 | sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, | 188 | sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, |
186 | sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem | 189 | sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups |
187 | } ServerOpCodes; | 190 | } ServerOpCodes; |
188 | 191 | ||
189 | /* Textual representation of the tokens. */ | 192 | /* Textual representation of the tokens. */ |
@@ -239,6 +242,7 @@ static struct { | |||
239 | { "protocol", sProtocol }, | 242 | { "protocol", sProtocol }, |
240 | { "gatewayports", sGatewayPorts }, | 243 | { "gatewayports", sGatewayPorts }, |
241 | { "subsystem", sSubsystem }, | 244 | { "subsystem", sSubsystem }, |
245 | { "maxstartups", sMaxStartups }, | ||
242 | { NULL, 0 } | 246 | { NULL, 0 } |
243 | }; | 247 | }; |
244 | 248 | ||
@@ -300,7 +304,7 @@ read_server_config(ServerOptions *options, const char *filename) | |||
300 | { | 304 | { |
301 | FILE *f; | 305 | FILE *f; |
302 | char line[1024]; | 306 | char line[1024]; |
303 | char *cp, **charptr; | 307 | char *cp, **charptr, *arg; |
304 | int linenum, *intptr, value; | 308 | int linenum, *intptr, value; |
305 | int bad_options = 0; | 309 | int bad_options = 0; |
306 | ServerOpCodes opcode; | 310 | ServerOpCodes opcode; |
@@ -317,8 +321,8 @@ read_server_config(ServerOptions *options, const char *filename) | |||
317 | cp = line + strspn(line, WHITESPACE); | 321 | cp = line + strspn(line, WHITESPACE); |
318 | if (!*cp || *cp == '#') | 322 | if (!*cp || *cp == '#') |
319 | continue; | 323 | continue; |
320 | cp = strtok(cp, WHITESPACE); | 324 | arg = strsep(&cp, WHITESPACE); |
321 | opcode = parse_token(cp, filename, linenum); | 325 | opcode = parse_token(arg, filename, linenum); |
322 | switch (opcode) { | 326 | switch (opcode) { |
323 | case sBadOption: | 327 | case sBadOption: |
324 | bad_options++; | 328 | bad_options++; |
@@ -333,23 +337,23 @@ read_server_config(ServerOptions *options, const char *filename) | |||
333 | if (options->num_ports >= MAX_PORTS) | 337 | if (options->num_ports >= MAX_PORTS) |
334 | fatal("%s line %d: too many ports.\n", | 338 | fatal("%s line %d: too many ports.\n", |
335 | filename, linenum); | 339 | filename, linenum); |
336 | cp = strtok(NULL, WHITESPACE); | 340 | arg = strsep(&cp, WHITESPACE); |
337 | if (!cp) | 341 | if (!arg || *arg == '\0') |
338 | fatal("%s line %d: missing port number.\n", | 342 | fatal("%s line %d: missing port number.\n", |
339 | filename, linenum); | 343 | filename, linenum); |
340 | options->ports[options->num_ports++] = atoi(cp); | 344 | options->ports[options->num_ports++] = atoi(arg); |
341 | break; | 345 | break; |
342 | 346 | ||
343 | case sServerKeyBits: | 347 | case sServerKeyBits: |
344 | intptr = &options->server_key_bits; | 348 | intptr = &options->server_key_bits; |
345 | parse_int: | 349 | parse_int: |
346 | cp = strtok(NULL, WHITESPACE); | 350 | arg = strsep(&cp, WHITESPACE); |
347 | if (!cp) { | 351 | if (!arg || *arg == '\0') { |
348 | fprintf(stderr, "%s line %d: missing integer value.\n", | 352 | fprintf(stderr, "%s line %d: missing integer value.\n", |
349 | filename, linenum); | 353 | filename, linenum); |
350 | exit(1); | 354 | exit(1); |
351 | } | 355 | } |
352 | value = atoi(cp); | 356 | value = atoi(arg); |
353 | if (*intptr == -1) | 357 | if (*intptr == -1) |
354 | *intptr = value; | 358 | *intptr = value; |
355 | break; | 359 | break; |
@@ -363,11 +367,11 @@ parse_int: | |||
363 | goto parse_int; | 367 | goto parse_int; |
364 | 368 | ||
365 | case sListenAddress: | 369 | case sListenAddress: |
366 | cp = strtok(NULL, WHITESPACE); | 370 | arg = strsep(&cp, WHITESPACE); |
367 | if (!cp) | 371 | if (!arg || *arg == '\0') |
368 | fatal("%s line %d: missing inet addr.\n", | 372 | fatal("%s line %d: missing inet addr.\n", |
369 | filename, linenum); | 373 | filename, linenum); |
370 | add_listen_addr(options, cp); | 374 | add_listen_addr(options, arg); |
371 | break; | 375 | break; |
372 | 376 | ||
373 | case sHostKeyFile: | 377 | case sHostKeyFile: |
@@ -375,14 +379,14 @@ parse_int: | |||
375 | charptr = (opcode == sHostKeyFile ) ? | 379 | charptr = (opcode == sHostKeyFile ) ? |
376 | &options->host_key_file : &options->host_dsa_key_file; | 380 | &options->host_key_file : &options->host_dsa_key_file; |
377 | parse_filename: | 381 | parse_filename: |
378 | cp = strtok(NULL, WHITESPACE); | 382 | arg = strsep(&cp, WHITESPACE); |
379 | if (!cp) { | 383 | if (!arg || *arg == '\0') { |
380 | fprintf(stderr, "%s line %d: missing file name.\n", | 384 | fprintf(stderr, "%s line %d: missing file name.\n", |
381 | filename, linenum); | 385 | filename, linenum); |
382 | exit(1); | 386 | exit(1); |
383 | } | 387 | } |
384 | if (*charptr == NULL) | 388 | if (*charptr == NULL) |
385 | *charptr = tilde_expand_filename(cp, getuid()); | 389 | *charptr = tilde_expand_filename(arg, getuid()); |
386 | break; | 390 | break; |
387 | 391 | ||
388 | case sPidFile: | 392 | case sPidFile: |
@@ -392,26 +396,26 @@ parse_filename: | |||
392 | case sRandomSeedFile: | 396 | case sRandomSeedFile: |
393 | fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", | 397 | fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", |
394 | filename, linenum); | 398 | filename, linenum); |
395 | cp = strtok(NULL, WHITESPACE); | 399 | arg = strsep(&cp, WHITESPACE); |
396 | break; | 400 | break; |
397 | 401 | ||
398 | case sPermitRootLogin: | 402 | case sPermitRootLogin: |
399 | intptr = &options->permit_root_login; | 403 | intptr = &options->permit_root_login; |
400 | cp = strtok(NULL, WHITESPACE); | 404 | arg = strsep(&cp, WHITESPACE); |
401 | if (!cp) { | 405 | if (!arg || *arg == '\0') { |
402 | fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", | 406 | fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", |
403 | filename, linenum); | 407 | filename, linenum); |
404 | exit(1); | 408 | exit(1); |
405 | } | 409 | } |
406 | if (strcmp(cp, "without-password") == 0) | 410 | if (strcmp(arg, "without-password") == 0) |
407 | value = 2; | 411 | value = 2; |
408 | else if (strcmp(cp, "yes") == 0) | 412 | else if (strcmp(arg, "yes") == 0) |
409 | value = 1; | 413 | value = 1; |
410 | else if (strcmp(cp, "no") == 0) | 414 | else if (strcmp(arg, "no") == 0) |
411 | value = 0; | 415 | value = 0; |
412 | else { | 416 | else { |
413 | fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", | 417 | fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", |
414 | filename, linenum, cp); | 418 | filename, linenum, arg); |
415 | exit(1); | 419 | exit(1); |
416 | } | 420 | } |
417 | if (*intptr == -1) | 421 | if (*intptr == -1) |
@@ -421,19 +425,19 @@ parse_filename: | |||
421 | case sIgnoreRhosts: | 425 | case sIgnoreRhosts: |
422 | intptr = &options->ignore_rhosts; | 426 | intptr = &options->ignore_rhosts; |
423 | parse_flag: | 427 | parse_flag: |
424 | cp = strtok(NULL, WHITESPACE); | 428 | arg = strsep(&cp, WHITESPACE); |
425 | if (!cp) { | 429 | if (!arg || *arg == '\0') { |
426 | fprintf(stderr, "%s line %d: missing yes/no argument.\n", | 430 | fprintf(stderr, "%s line %d: missing yes/no argument.\n", |
427 | filename, linenum); | 431 | filename, linenum); |
428 | exit(1); | 432 | exit(1); |
429 | } | 433 | } |
430 | if (strcmp(cp, "yes") == 0) | 434 | if (strcmp(arg, "yes") == 0) |
431 | value = 1; | 435 | value = 1; |
432 | else if (strcmp(cp, "no") == 0) | 436 | else if (strcmp(arg, "no") == 0) |
433 | value = 0; | 437 | value = 0; |
434 | else { | 438 | else { |
435 | fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", | 439 | fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", |
436 | filename, linenum, cp); | 440 | filename, linenum, arg); |
437 | exit(1); | 441 | exit(1); |
438 | } | 442 | } |
439 | if (*intptr == -1) | 443 | if (*intptr == -1) |
@@ -536,82 +540,82 @@ parse_flag: | |||
536 | 540 | ||
537 | case sLogFacility: | 541 | case sLogFacility: |
538 | intptr = (int *) &options->log_facility; | 542 | intptr = (int *) &options->log_facility; |
539 | cp = strtok(NULL, WHITESPACE); | 543 | arg = strsep(&cp, WHITESPACE); |
540 | value = log_facility_number(cp); | 544 | value = log_facility_number(arg); |
541 | if (value == (SyslogFacility) - 1) | 545 | if (value == (SyslogFacility) - 1) |
542 | fatal("%.200s line %d: unsupported log facility '%s'\n", | 546 | fatal("%.200s line %d: unsupported log facility '%s'\n", |
543 | filename, linenum, cp ? cp : "<NONE>"); | 547 | filename, linenum, arg ? arg : "<NONE>"); |
544 | if (*intptr == -1) | 548 | if (*intptr == -1) |
545 | *intptr = (SyslogFacility) value; | 549 | *intptr = (SyslogFacility) value; |
546 | break; | 550 | break; |
547 | 551 | ||
548 | case sLogLevel: | 552 | case sLogLevel: |
549 | intptr = (int *) &options->log_level; | 553 | intptr = (int *) &options->log_level; |
550 | cp = strtok(NULL, WHITESPACE); | 554 | arg = strsep(&cp, WHITESPACE); |
551 | value = log_level_number(cp); | 555 | value = log_level_number(arg); |
552 | if (value == (LogLevel) - 1) | 556 | if (value == (LogLevel) - 1) |
553 | fatal("%.200s line %d: unsupported log level '%s'\n", | 557 | fatal("%.200s line %d: unsupported log level '%s'\n", |
554 | filename, linenum, cp ? cp : "<NONE>"); | 558 | filename, linenum, arg ? arg : "<NONE>"); |
555 | if (*intptr == -1) | 559 | if (*intptr == -1) |
556 | *intptr = (LogLevel) value; | 560 | *intptr = (LogLevel) value; |
557 | break; | 561 | break; |
558 | 562 | ||
559 | case sAllowUsers: | 563 | case sAllowUsers: |
560 | while ((cp = strtok(NULL, WHITESPACE))) { | 564 | while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') { |
561 | if (options->num_allow_users >= MAX_ALLOW_USERS) | 565 | if (options->num_allow_users >= MAX_ALLOW_USERS) |
562 | fatal("%s line %d: too many allow users.\n", | 566 | fatal("%s line %d: too many allow users.\n", |
563 | filename, linenum); | 567 | filename, linenum); |
564 | options->allow_users[options->num_allow_users++] = xstrdup(cp); | 568 | options->allow_users[options->num_allow_users++] = xstrdup(arg); |
565 | } | 569 | } |
566 | break; | 570 | break; |
567 | 571 | ||
568 | case sDenyUsers: | 572 | case sDenyUsers: |
569 | while ((cp = strtok(NULL, WHITESPACE))) { | 573 | while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') { |
570 | if (options->num_deny_users >= MAX_DENY_USERS) | 574 | if (options->num_deny_users >= MAX_DENY_USERS) |
571 | fatal( "%s line %d: too many deny users.\n", | 575 | fatal( "%s line %d: too many deny users.\n", |
572 | filename, linenum); | 576 | filename, linenum); |
573 | options->deny_users[options->num_deny_users++] = xstrdup(cp); | 577 | options->deny_users[options->num_deny_users++] = xstrdup(arg); |
574 | } | 578 | } |
575 | break; | 579 | break; |
576 | 580 | ||
577 | case sAllowGroups: | 581 | case sAllowGroups: |
578 | while ((cp = strtok(NULL, WHITESPACE))) { | 582 | while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') { |
579 | if (options->num_allow_groups >= MAX_ALLOW_GROUPS) | 583 | if (options->num_allow_groups >= MAX_ALLOW_GROUPS) |
580 | fatal("%s line %d: too many allow groups.\n", | 584 | fatal("%s line %d: too many allow groups.\n", |
581 | filename, linenum); | 585 | filename, linenum); |
582 | options->allow_groups[options->num_allow_groups++] = xstrdup(cp); | 586 | options->allow_groups[options->num_allow_groups++] = xstrdup(arg); |
583 | } | 587 | } |
584 | break; | 588 | break; |
585 | 589 | ||
586 | case sDenyGroups: | 590 | case sDenyGroups: |
587 | while ((cp = strtok(NULL, WHITESPACE))) { | 591 | while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') { |
588 | if (options->num_deny_groups >= MAX_DENY_GROUPS) | 592 | if (options->num_deny_groups >= MAX_DENY_GROUPS) |
589 | fatal("%s line %d: too many deny groups.\n", | 593 | fatal("%s line %d: too many deny groups.\n", |
590 | filename, linenum); | 594 | filename, linenum); |
591 | options->deny_groups[options->num_deny_groups++] = xstrdup(cp); | 595 | options->deny_groups[options->num_deny_groups++] = xstrdup(arg); |
592 | } | 596 | } |
593 | break; | 597 | break; |
594 | 598 | ||
595 | case sCiphers: | 599 | case sCiphers: |
596 | cp = strtok(NULL, WHITESPACE); | 600 | arg = strsep(&cp, WHITESPACE); |
597 | if (!cp) | 601 | if (!arg || *arg == '\0') |
598 | fatal("%s line %d: Missing argument.", filename, linenum); | 602 | fatal("%s line %d: Missing argument.", filename, linenum); |
599 | if (!ciphers_valid(cp)) | 603 | if (!ciphers_valid(arg)) |
600 | fatal("%s line %d: Bad SSH2 cipher spec '%s'.", | 604 | fatal("%s line %d: Bad SSH2 cipher spec '%s'.", |
601 | filename, linenum, cp ? cp : "<NONE>"); | 605 | filename, linenum, arg ? arg : "<NONE>"); |
602 | if (options->ciphers == NULL) | 606 | if (options->ciphers == NULL) |
603 | options->ciphers = xstrdup(cp); | 607 | options->ciphers = xstrdup(arg); |
604 | break; | 608 | break; |
605 | 609 | ||
606 | case sProtocol: | 610 | case sProtocol: |
607 | intptr = &options->protocol; | 611 | intptr = &options->protocol; |
608 | cp = strtok(NULL, WHITESPACE); | 612 | arg = strsep(&cp, WHITESPACE); |
609 | if (!cp) | 613 | if (!arg || *arg == '\0') |
610 | fatal("%s line %d: Missing argument.", filename, linenum); | 614 | fatal("%s line %d: Missing argument.", filename, linenum); |
611 | value = proto_spec(cp); | 615 | value = proto_spec(arg); |
612 | if (value == SSH_PROTO_UNKNOWN) | 616 | if (value == SSH_PROTO_UNKNOWN) |
613 | fatal("%s line %d: Bad protocol spec '%s'.", | 617 | fatal("%s line %d: Bad protocol spec '%s'.", |
614 | filename, linenum, cp ? cp : "<NONE>"); | 618 | filename, linenum, arg ? arg : "<NONE>"); |
615 | if (*intptr == SSH_PROTO_UNKNOWN) | 619 | if (*intptr == SSH_PROTO_UNKNOWN) |
616 | *intptr = value; | 620 | *intptr = value; |
617 | break; | 621 | break; |
@@ -621,31 +625,36 @@ parse_flag: | |||
621 | fatal("%s line %d: too many subsystems defined.", | 625 | fatal("%s line %d: too many subsystems defined.", |
622 | filename, linenum); | 626 | filename, linenum); |
623 | } | 627 | } |
624 | cp = strtok(NULL, WHITESPACE); | 628 | arg = strsep(&cp, WHITESPACE); |
625 | if (!cp) | 629 | if (!arg || *arg == '\0') |
626 | fatal("%s line %d: Missing subsystem name.", | 630 | fatal("%s line %d: Missing subsystem name.", |
627 | filename, linenum); | 631 | filename, linenum); |
628 | for (i = 0; i < options->num_subsystems; i++) | 632 | for (i = 0; i < options->num_subsystems; i++) |
629 | if(strcmp(cp, options->subsystem_name[i]) == 0) | 633 | if(strcmp(arg, options->subsystem_name[i]) == 0) |
630 | fatal("%s line %d: Subsystem '%s' already defined.", | 634 | fatal("%s line %d: Subsystem '%s' already defined.", |
631 | filename, linenum, cp); | 635 | filename, linenum, arg); |
632 | options->subsystem_name[options->num_subsystems] = xstrdup(cp); | 636 | options->subsystem_name[options->num_subsystems] = xstrdup(arg); |
633 | cp = strtok(NULL, WHITESPACE); | 637 | arg = strsep(&cp, WHITESPACE); |
634 | if (!cp) | 638 | if (!arg || *arg == '\0') |
635 | fatal("%s line %d: Missing subsystem command.", | 639 | fatal("%s line %d: Missing subsystem command.", |
636 | filename, linenum); | 640 | filename, linenum); |
637 | options->subsystem_command[options->num_subsystems] = xstrdup(cp); | 641 | options->subsystem_command[options->num_subsystems] = xstrdup(arg); |
638 | options->num_subsystems++; | 642 | options->num_subsystems++; |
639 | break; | 643 | break; |
640 | 644 | ||
645 | case sMaxStartups: | ||
646 | intptr = &options->max_startups; | ||
647 | goto parse_int; | ||
648 | |||
641 | default: | 649 | default: |
642 | fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", | 650 | fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", |
643 | filename, linenum, cp, opcode); | 651 | filename, linenum, arg, opcode); |
644 | exit(1); | 652 | exit(1); |
645 | } | 653 | } |
646 | if (strtok(NULL, WHITESPACE) != NULL) { | 654 | if ((arg = strsep(&cp, WHITESPACE)) != NULL && *arg != '\0') { |
647 | fprintf(stderr, "%s line %d: garbage at end of line.\n", | 655 | fprintf(stderr, |
648 | filename, linenum); | 656 | "%s line %d: garbage at end of line; \"%.200s\".\n", |
657 | filename, linenum, arg); | ||
649 | exit(1); | 658 | exit(1); |
650 | } | 659 | } |
651 | } | 660 | } |