diff options
Diffstat (limited to 'servconf.c')
-rw-r--r-- | servconf.c | 888 |
1 files changed, 449 insertions, 439 deletions
diff --git a/servconf.c b/servconf.c index bd5588609..0f0a7396b 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include "includes.h" | 12 | #include "includes.h" |
13 | RCSID("$OpenBSD: servconf.c,v 1.93 2001/12/05 10:06:12 deraadt Exp $"); | 13 | RCSID("$OpenBSD: servconf.c,v 1.94 2001/12/06 13:30:05 markus Exp $"); |
14 | 14 | ||
15 | #if defined(KRB4) || defined(KRB5) | 15 | #if defined(KRB4) || defined(KRB5) |
16 | #include <krb.h> | 16 | #include <krb.h> |
@@ -261,7 +261,7 @@ typedef enum { | |||
261 | sBanner, sReverseMappingCheck, sHostbasedAuthentication, | 261 | sBanner, sReverseMappingCheck, sHostbasedAuthentication, |
262 | sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, | 262 | sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, |
263 | sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, | 263 | sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, |
264 | sDeprecated | 264 | sDeprecated |
265 | } ServerOpCodes; | 265 | } ServerOpCodes; |
266 | 266 | ||
267 | /* Textual representation of the tokens. */ | 267 | /* Textual representation of the tokens. */ |
@@ -392,487 +392,497 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port) | |||
392 | options->listen_addrs = aitop; | 392 | options->listen_addrs = aitop; |
393 | } | 393 | } |
394 | 394 | ||
395 | /* Reads the server configuration file. */ | 395 | int |
396 | 396 | process_server_config_line(ServerOptions *options, char *line, | |
397 | void | 397 | const char *filename, int linenum) |
398 | read_server_config(ServerOptions *options, const char *filename) | ||
399 | { | 398 | { |
400 | FILE *f; | ||
401 | char line[1024]; | ||
402 | char *cp, **charptr, *arg, *p; | 399 | char *cp, **charptr, *arg, *p; |
403 | int linenum, *intptr, value; | 400 | int *intptr, value; |
404 | int bad_options = 0; | ||
405 | ServerOpCodes opcode; | 401 | ServerOpCodes opcode; |
406 | int i, n; | 402 | int i, n; |
407 | 403 | ||
408 | f = fopen(filename, "r"); | 404 | cp = line; |
409 | if (!f) { | 405 | arg = strdelim(&cp); |
410 | perror(filename); | 406 | /* Ignore leading whitespace */ |
411 | exit(1); | 407 | if (*arg == '\0') |
412 | } | ||
413 | linenum = 0; | ||
414 | while (fgets(line, sizeof(line), f)) { | ||
415 | linenum++; | ||
416 | cp = line; | ||
417 | arg = strdelim(&cp); | 408 | arg = strdelim(&cp); |
418 | /* Ignore leading whitespace */ | 409 | if (!arg || !*arg || *arg == '#') |
419 | if (*arg == '\0') | 410 | return 0; |
420 | arg = strdelim(&cp); | 411 | intptr = NULL; |
421 | if (!arg || !*arg || *arg == '#') | 412 | charptr = NULL; |
422 | continue; | 413 | opcode = parse_token(arg, filename, linenum); |
423 | intptr = NULL; | 414 | switch (opcode) { |
424 | charptr = NULL; | 415 | /* Portable-specific options */ |
425 | opcode = parse_token(arg, filename, linenum); | 416 | case sPAMAuthenticationViaKbdInt: |
426 | switch (opcode) { | 417 | intptr = &options->pam_authentication_via_kbd_int; |
427 | case sBadOption: | 418 | goto parse_flag; |
428 | bad_options++; | ||
429 | continue; | ||
430 | |||
431 | /* Portable-specific options */ | ||
432 | case sPAMAuthenticationViaKbdInt: | ||
433 | intptr = &options->pam_authentication_via_kbd_int; | ||
434 | goto parse_flag; | ||
435 | |||
436 | /* Standard Options */ | ||
437 | case sPort: | ||
438 | /* ignore ports from configfile if cmdline specifies ports */ | ||
439 | if (options->ports_from_cmdline) | ||
440 | continue; | ||
441 | if (options->listen_addrs != NULL) | ||
442 | fatal("%s line %d: ports must be specified before " | ||
443 | "ListenAdress.", filename, linenum); | ||
444 | if (options->num_ports >= MAX_PORTS) | ||
445 | fatal("%s line %d: too many ports.", | ||
446 | filename, linenum); | ||
447 | arg = strdelim(&cp); | ||
448 | if (!arg || *arg == '\0') | ||
449 | fatal("%s line %d: missing port number.", | ||
450 | filename, linenum); | ||
451 | options->ports[options->num_ports++] = a2port(arg); | ||
452 | if (options->ports[options->num_ports-1] == 0) | ||
453 | fatal("%s line %d: Badly formatted port number.", | ||
454 | filename, linenum); | ||
455 | break; | ||
456 | 419 | ||
457 | case sServerKeyBits: | 420 | /* Standard Options */ |
458 | intptr = &options->server_key_bits; | 421 | case sBadOption: |
422 | return -1; | ||
423 | case sPort: | ||
424 | /* ignore ports from configfile if cmdline specifies ports */ | ||
425 | if (options->ports_from_cmdline) | ||
426 | return 0; | ||
427 | if (options->listen_addrs != NULL) | ||
428 | fatal("%s line %d: ports must be specified before " | ||
429 | "ListenAdress.", filename, linenum); | ||
430 | if (options->num_ports >= MAX_PORTS) | ||
431 | fatal("%s line %d: too many ports.", | ||
432 | filename, linenum); | ||
433 | arg = strdelim(&cp); | ||
434 | if (!arg || *arg == '\0') | ||
435 | fatal("%s line %d: missing port number.", | ||
436 | filename, linenum); | ||
437 | options->ports[options->num_ports++] = a2port(arg); | ||
438 | if (options->ports[options->num_ports-1] == 0) | ||
439 | fatal("%s line %d: Badly formatted port number.", | ||
440 | filename, linenum); | ||
441 | break; | ||
442 | |||
443 | case sServerKeyBits: | ||
444 | intptr = &options->server_key_bits; | ||
459 | parse_int: | 445 | parse_int: |
460 | arg = strdelim(&cp); | 446 | arg = strdelim(&cp); |
461 | if (!arg || *arg == '\0') | 447 | if (!arg || *arg == '\0') |
462 | fatal("%s line %d: missing integer value.", | 448 | fatal("%s line %d: missing integer value.", |
463 | filename, linenum); | 449 | filename, linenum); |
464 | value = atoi(arg); | 450 | value = atoi(arg); |
465 | if (*intptr == -1) | 451 | if (*intptr == -1) |
466 | *intptr = value; | 452 | *intptr = value; |
467 | break; | 453 | break; |
468 | 454 | ||
469 | case sLoginGraceTime: | 455 | case sLoginGraceTime: |
470 | intptr = &options->login_grace_time; | 456 | intptr = &options->login_grace_time; |
471 | parse_time: | 457 | parse_time: |
472 | arg = strdelim(&cp); | 458 | arg = strdelim(&cp); |
473 | if (!arg || *arg == '\0') | 459 | if (!arg || *arg == '\0') |
474 | fatal("%s line %d: missing time value.", | 460 | fatal("%s line %d: missing time value.", |
475 | filename, linenum); | 461 | filename, linenum); |
476 | if ((value = convtime(arg)) == -1) | 462 | if ((value = convtime(arg)) == -1) |
477 | fatal("%s line %d: invalid time value.", | 463 | fatal("%s line %d: invalid time value.", |
464 | filename, linenum); | ||
465 | if (*intptr == -1) | ||
466 | *intptr = value; | ||
467 | break; | ||
468 | |||
469 | case sKeyRegenerationTime: | ||
470 | intptr = &options->key_regeneration_time; | ||
471 | goto parse_time; | ||
472 | |||
473 | case sListenAddress: | ||
474 | arg = strdelim(&cp); | ||
475 | if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) | ||
476 | fatal("%s line %d: missing inet addr.", | ||
477 | filename, linenum); | ||
478 | if (*arg == '[') { | ||
479 | if ((p = strchr(arg, ']')) == NULL) | ||
480 | fatal("%s line %d: bad ipv6 inet addr usage.", | ||
478 | filename, linenum); | 481 | filename, linenum); |
479 | if (*intptr == -1) | 482 | arg++; |
480 | *intptr = value; | 483 | memmove(p, p+1, strlen(p+1)+1); |
484 | } else if (((p = strchr(arg, ':')) == NULL) || | ||
485 | (strchr(p+1, ':') != NULL)) { | ||
486 | add_listen_addr(options, arg, 0); | ||
481 | break; | 487 | break; |
488 | } | ||
489 | if (*p == ':') { | ||
490 | u_short port; | ||
482 | 491 | ||
483 | case sKeyRegenerationTime: | 492 | p++; |
484 | intptr = &options->key_regeneration_time; | 493 | if (*p == '\0') |
485 | goto parse_time; | 494 | fatal("%s line %d: bad inet addr:port usage.", |
486 | |||
487 | case sListenAddress: | ||
488 | arg = strdelim(&cp); | ||
489 | if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) | ||
490 | fatal("%s line %d: missing inet addr.", | ||
491 | filename, linenum); | 495 | filename, linenum); |
492 | if (*arg == '[') { | 496 | else { |
493 | if ((p = strchr(arg, ']')) == NULL) | 497 | *(p-1) = '\0'; |
494 | fatal("%s line %d: bad ipv6 inet addr usage.", | 498 | if ((port = a2port(p)) == 0) |
499 | fatal("%s line %d: bad port number.", | ||
495 | filename, linenum); | 500 | filename, linenum); |
496 | arg++; | 501 | add_listen_addr(options, arg, port); |
497 | memmove(p, p+1, strlen(p+1)+1); | ||
498 | } else if (((p = strchr(arg, ':')) == NULL) || | ||
499 | (strchr(p+1, ':') != NULL)) { | ||
500 | add_listen_addr(options, arg, 0); | ||
501 | break; | ||
502 | } | 502 | } |
503 | if (*p == ':') { | 503 | } else if (*p == '\0') |
504 | u_short port; | 504 | add_listen_addr(options, arg, 0); |
505 | 505 | else | |
506 | p++; | 506 | fatal("%s line %d: bad inet addr usage.", |
507 | if (*p == '\0') | 507 | filename, linenum); |
508 | fatal("%s line %d: bad inet addr:port usage.", | 508 | break; |
509 | filename, linenum); | 509 | |
510 | else { | 510 | case sHostKeyFile: |
511 | *(p-1) = '\0'; | 511 | intptr = &options->num_host_key_files; |
512 | if ((port = a2port(p)) == 0) | 512 | if (*intptr >= MAX_HOSTKEYS) |
513 | fatal("%s line %d: bad port number.", | 513 | fatal("%s line %d: too many host keys specified (max %d).", |
514 | filename, linenum); | 514 | filename, linenum, MAX_HOSTKEYS); |
515 | add_listen_addr(options, arg, port); | 515 | charptr = &options->host_key_files[*intptr]; |
516 | } | ||
517 | } else if (*p == '\0') | ||
518 | add_listen_addr(options, arg, 0); | ||
519 | else | ||
520 | fatal("%s line %d: bad inet addr usage.", | ||
521 | filename, linenum); | ||
522 | break; | ||
523 | |||
524 | case sHostKeyFile: | ||
525 | intptr = &options->num_host_key_files; | ||
526 | if (*intptr >= MAX_HOSTKEYS) | ||
527 | fatal("%s line %d: too many host keys specified (max %d).", | ||
528 | filename, linenum, MAX_HOSTKEYS); | ||
529 | charptr = &options->host_key_files[*intptr]; | ||
530 | parse_filename: | 516 | parse_filename: |
531 | arg = strdelim(&cp); | 517 | arg = strdelim(&cp); |
532 | if (!arg || *arg == '\0') | 518 | if (!arg || *arg == '\0') |
533 | fatal("%s line %d: missing file name.", | 519 | fatal("%s line %d: missing file name.", |
534 | filename, linenum); | 520 | filename, linenum); |
535 | if (*charptr == NULL) { | 521 | if (*charptr == NULL) { |
536 | *charptr = tilde_expand_filename(arg, getuid()); | 522 | *charptr = tilde_expand_filename(arg, getuid()); |
537 | /* increase optional counter */ | 523 | /* increase optional counter */ |
538 | if (intptr != NULL) | 524 | if (intptr != NULL) |
539 | *intptr = *intptr + 1; | 525 | *intptr = *intptr + 1; |
540 | } | 526 | } |
541 | break; | 527 | break; |
542 | 528 | ||
543 | case sPidFile: | 529 | case sPidFile: |
544 | charptr = &options->pid_file; | 530 | charptr = &options->pid_file; |
545 | goto parse_filename; | 531 | goto parse_filename; |
546 | |||
547 | case sPermitRootLogin: | ||
548 | intptr = &options->permit_root_login; | ||
549 | arg = strdelim(&cp); | ||
550 | if (!arg || *arg == '\0') | ||
551 | fatal("%s line %d: missing yes/" | ||
552 | "without-password/forced-commands-only/no " | ||
553 | "argument.", filename, linenum); | ||
554 | value = 0; /* silence compiler */ | ||
555 | if (strcmp(arg, "without-password") == 0) | ||
556 | value = PERMIT_NO_PASSWD; | ||
557 | else if (strcmp(arg, "forced-commands-only") == 0) | ||
558 | value = PERMIT_FORCED_ONLY; | ||
559 | else if (strcmp(arg, "yes") == 0) | ||
560 | value = PERMIT_YES; | ||
561 | else if (strcmp(arg, "no") == 0) | ||
562 | value = PERMIT_NO; | ||
563 | else | ||
564 | fatal("%s line %d: Bad yes/" | ||
565 | "without-password/forced-commands-only/no " | ||
566 | "argument: %s", filename, linenum, arg); | ||
567 | if (*intptr == -1) | ||
568 | *intptr = value; | ||
569 | break; | ||
570 | 532 | ||
571 | case sIgnoreRhosts: | 533 | case sPermitRootLogin: |
572 | intptr = &options->ignore_rhosts; | 534 | intptr = &options->permit_root_login; |
535 | arg = strdelim(&cp); | ||
536 | if (!arg || *arg == '\0') | ||
537 | fatal("%s line %d: missing yes/" | ||
538 | "without-password/forced-commands-only/no " | ||
539 | "argument.", filename, linenum); | ||
540 | value = 0; /* silence compiler */ | ||
541 | if (strcmp(arg, "without-password") == 0) | ||
542 | value = PERMIT_NO_PASSWD; | ||
543 | else if (strcmp(arg, "forced-commands-only") == 0) | ||
544 | value = PERMIT_FORCED_ONLY; | ||
545 | else if (strcmp(arg, "yes") == 0) | ||
546 | value = PERMIT_YES; | ||
547 | else if (strcmp(arg, "no") == 0) | ||
548 | value = PERMIT_NO; | ||
549 | else | ||
550 | fatal("%s line %d: Bad yes/" | ||
551 | "without-password/forced-commands-only/no " | ||
552 | "argument: %s", filename, linenum, arg); | ||
553 | if (*intptr == -1) | ||
554 | *intptr = value; | ||
555 | break; | ||
556 | |||
557 | case sIgnoreRhosts: | ||
558 | intptr = &options->ignore_rhosts; | ||
573 | parse_flag: | 559 | parse_flag: |
574 | arg = strdelim(&cp); | 560 | arg = strdelim(&cp); |
575 | if (!arg || *arg == '\0') | 561 | if (!arg || *arg == '\0') |
576 | fatal("%s line %d: missing yes/no argument.", | 562 | fatal("%s line %d: missing yes/no argument.", |
577 | filename, linenum); | 563 | filename, linenum); |
578 | value = 0; /* silence compiler */ | 564 | value = 0; /* silence compiler */ |
579 | if (strcmp(arg, "yes") == 0) | 565 | if (strcmp(arg, "yes") == 0) |
580 | value = 1; | 566 | value = 1; |
581 | else if (strcmp(arg, "no") == 0) | 567 | else if (strcmp(arg, "no") == 0) |
582 | value = 0; | 568 | value = 0; |
583 | else | 569 | else |
584 | fatal("%s line %d: Bad yes/no argument: %s", | 570 | fatal("%s line %d: Bad yes/no argument: %s", |
585 | filename, linenum, arg); | 571 | filename, linenum, arg); |
586 | if (*intptr == -1) | 572 | if (*intptr == -1) |
587 | *intptr = value; | 573 | *intptr = value; |
588 | break; | 574 | break; |
575 | |||
576 | case sIgnoreUserKnownHosts: | ||
577 | intptr = &options->ignore_user_known_hosts; | ||
578 | goto parse_flag; | ||
579 | |||
580 | case sRhostsAuthentication: | ||
581 | intptr = &options->rhosts_authentication; | ||
582 | goto parse_flag; | ||
583 | |||
584 | case sRhostsRSAAuthentication: | ||
585 | intptr = &options->rhosts_rsa_authentication; | ||
586 | goto parse_flag; | ||
587 | |||
588 | case sHostbasedAuthentication: | ||
589 | intptr = &options->hostbased_authentication; | ||
590 | goto parse_flag; | ||
591 | |||
592 | case sHostbasedUsesNameFromPacketOnly: | ||
593 | intptr = &options->hostbased_uses_name_from_packet_only; | ||
594 | goto parse_flag; | ||
595 | |||
596 | case sRSAAuthentication: | ||
597 | intptr = &options->rsa_authentication; | ||
598 | goto parse_flag; | ||
599 | |||
600 | case sPubkeyAuthentication: | ||
601 | intptr = &options->pubkey_authentication; | ||
602 | goto parse_flag; | ||
603 | #if defined(KRB4) || defined(KRB5) | ||
604 | case sKerberosAuthentication: | ||
605 | intptr = &options->kerberos_authentication; | ||
606 | goto parse_flag; | ||
589 | 607 | ||
590 | case sIgnoreUserKnownHosts: | 608 | case sKerberosOrLocalPasswd: |
591 | intptr = &options->ignore_user_known_hosts; | 609 | intptr = &options->kerberos_or_local_passwd; |
592 | goto parse_flag; | 610 | goto parse_flag; |
593 | 611 | ||
594 | case sRhostsAuthentication: | 612 | case sKerberosTicketCleanup: |
595 | intptr = &options->rhosts_authentication; | 613 | intptr = &options->kerberos_ticket_cleanup; |
596 | goto parse_flag; | 614 | goto parse_flag; |
615 | #endif | ||
616 | #if defined(AFS) || defined(KRB5) | ||
617 | case sKerberosTgtPassing: | ||
618 | intptr = &options->kerberos_tgt_passing; | ||
619 | goto parse_flag; | ||
620 | #endif | ||
621 | #ifdef AFS | ||
622 | case sAFSTokenPassing: | ||
623 | intptr = &options->afs_token_passing; | ||
624 | goto parse_flag; | ||
625 | #endif | ||
597 | 626 | ||
598 | case sRhostsRSAAuthentication: | 627 | case sPasswordAuthentication: |
599 | intptr = &options->rhosts_rsa_authentication; | 628 | intptr = &options->password_authentication; |
600 | goto parse_flag; | 629 | goto parse_flag; |
601 | 630 | ||
602 | case sHostbasedAuthentication: | 631 | case sKbdInteractiveAuthentication: |
603 | intptr = &options->hostbased_authentication; | 632 | intptr = &options->kbd_interactive_authentication; |
604 | goto parse_flag; | 633 | goto parse_flag; |
605 | 634 | ||
606 | case sHostbasedUsesNameFromPacketOnly: | 635 | case sChallengeResponseAuthentication: |
607 | intptr = &options->hostbased_uses_name_from_packet_only; | 636 | intptr = &options->challenge_response_authentication; |
608 | goto parse_flag; | 637 | goto parse_flag; |
609 | 638 | ||
610 | case sRSAAuthentication: | 639 | case sPrintMotd: |
611 | intptr = &options->rsa_authentication; | 640 | intptr = &options->print_motd; |
612 | goto parse_flag; | 641 | goto parse_flag; |
613 | 642 | ||
614 | case sPubkeyAuthentication: | 643 | case sPrintLastLog: |
615 | intptr = &options->pubkey_authentication; | 644 | intptr = &options->print_lastlog; |
616 | goto parse_flag; | 645 | goto parse_flag; |
617 | #if defined(KRB4) || defined(KRB5) | ||
618 | case sKerberosAuthentication: | ||
619 | intptr = &options->kerberos_authentication; | ||
620 | goto parse_flag; | ||
621 | 646 | ||
622 | case sKerberosOrLocalPasswd: | 647 | case sX11Forwarding: |
623 | intptr = &options->kerberos_or_local_passwd; | 648 | intptr = &options->x11_forwarding; |
624 | goto parse_flag; | 649 | goto parse_flag; |
625 | 650 | ||
626 | case sKerberosTicketCleanup: | 651 | case sX11DisplayOffset: |
627 | intptr = &options->kerberos_ticket_cleanup; | 652 | intptr = &options->x11_display_offset; |
628 | goto parse_flag; | 653 | goto parse_int; |
629 | #endif | ||
630 | #if defined(AFS) || defined(KRB5) | ||
631 | case sKerberosTgtPassing: | ||
632 | intptr = &options->kerberos_tgt_passing; | ||
633 | goto parse_flag; | ||
634 | #endif | ||
635 | #ifdef AFS | ||
636 | case sAFSTokenPassing: | ||
637 | intptr = &options->afs_token_passing; | ||
638 | goto parse_flag; | ||
639 | #endif | ||
640 | 654 | ||
641 | case sPasswordAuthentication: | 655 | case sXAuthLocation: |
642 | intptr = &options->password_authentication; | 656 | charptr = &options->xauth_location; |
643 | goto parse_flag; | 657 | goto parse_filename; |
644 | |||
645 | case sKbdInteractiveAuthentication: | ||
646 | intptr = &options->kbd_interactive_authentication; | ||
647 | goto parse_flag; | ||
648 | |||
649 | case sChallengeResponseAuthentication: | ||
650 | intptr = &options->challenge_response_authentication; | ||
651 | goto parse_flag; | ||
652 | |||
653 | case sPrintMotd: | ||
654 | intptr = &options->print_motd; | ||
655 | goto parse_flag; | ||
656 | |||
657 | case sPrintLastLog: | ||
658 | intptr = &options->print_lastlog; | ||
659 | goto parse_flag; | ||
660 | |||
661 | case sX11Forwarding: | ||
662 | intptr = &options->x11_forwarding; | ||
663 | goto parse_flag; | ||
664 | |||
665 | case sX11DisplayOffset: | ||
666 | intptr = &options->x11_display_offset; | ||
667 | goto parse_int; | ||
668 | |||
669 | case sXAuthLocation: | ||
670 | charptr = &options->xauth_location; | ||
671 | goto parse_filename; | ||
672 | |||
673 | case sStrictModes: | ||
674 | intptr = &options->strict_modes; | ||
675 | goto parse_flag; | ||
676 | |||
677 | case sKeepAlives: | ||
678 | intptr = &options->keepalives; | ||
679 | goto parse_flag; | ||
680 | |||
681 | case sEmptyPasswd: | ||
682 | intptr = &options->permit_empty_passwd; | ||
683 | goto parse_flag; | ||
684 | |||
685 | case sUseLogin: | ||
686 | intptr = &options->use_login; | ||
687 | goto parse_flag; | ||
688 | |||
689 | case sGatewayPorts: | ||
690 | intptr = &options->gateway_ports; | ||
691 | goto parse_flag; | ||
692 | |||
693 | case sReverseMappingCheck: | ||
694 | intptr = &options->reverse_mapping_check; | ||
695 | goto parse_flag; | ||
696 | |||
697 | case sLogFacility: | ||
698 | intptr = (int *) &options->log_facility; | ||
699 | arg = strdelim(&cp); | ||
700 | value = log_facility_number(arg); | ||
701 | if (value == (SyslogFacility) - 1) | ||
702 | fatal("%.200s line %d: unsupported log facility '%s'", | ||
703 | filename, linenum, arg ? arg : "<NONE>"); | ||
704 | if (*intptr == -1) | ||
705 | *intptr = (SyslogFacility) value; | ||
706 | break; | ||
707 | 658 | ||
708 | case sLogLevel: | 659 | case sStrictModes: |
709 | intptr = (int *) &options->log_level; | 660 | intptr = &options->strict_modes; |
710 | arg = strdelim(&cp); | 661 | goto parse_flag; |
711 | value = log_level_number(arg); | ||
712 | if (value == (LogLevel) - 1) | ||
713 | fatal("%.200s line %d: unsupported log level '%s'", | ||
714 | filename, linenum, arg ? arg : "<NONE>"); | ||
715 | if (*intptr == -1) | ||
716 | *intptr = (LogLevel) value; | ||
717 | break; | ||
718 | 662 | ||
719 | case sAllowTcpForwarding: | 663 | case sKeepAlives: |
720 | intptr = &options->allow_tcp_forwarding; | 664 | intptr = &options->keepalives; |
721 | goto parse_flag; | 665 | goto parse_flag; |
722 | 666 | ||
723 | case sAllowUsers: | 667 | case sEmptyPasswd: |
724 | while ((arg = strdelim(&cp)) && *arg != '\0') { | 668 | intptr = &options->permit_empty_passwd; |
725 | if (options->num_allow_users >= MAX_ALLOW_USERS) | 669 | goto parse_flag; |
726 | fatal("%s line %d: too many allow users.", | ||
727 | filename, linenum); | ||
728 | options->allow_users[options->num_allow_users++] = xstrdup(arg); | ||
729 | } | ||
730 | break; | ||
731 | 670 | ||
732 | case sDenyUsers: | 671 | case sUseLogin: |
733 | while ((arg = strdelim(&cp)) && *arg != '\0') { | 672 | intptr = &options->use_login; |
734 | if (options->num_deny_users >= MAX_DENY_USERS) | 673 | goto parse_flag; |
735 | fatal( "%s line %d: too many deny users.", | ||
736 | filename, linenum); | ||
737 | options->deny_users[options->num_deny_users++] = xstrdup(arg); | ||
738 | } | ||
739 | break; | ||
740 | 674 | ||
741 | case sAllowGroups: | 675 | case sGatewayPorts: |
742 | while ((arg = strdelim(&cp)) && *arg != '\0') { | 676 | intptr = &options->gateway_ports; |
743 | if (options->num_allow_groups >= MAX_ALLOW_GROUPS) | 677 | goto parse_flag; |
744 | fatal("%s line %d: too many allow groups.", | ||
745 | filename, linenum); | ||
746 | options->allow_groups[options->num_allow_groups++] = xstrdup(arg); | ||
747 | } | ||
748 | break; | ||
749 | 678 | ||
750 | case sDenyGroups: | 679 | case sReverseMappingCheck: |
751 | while ((arg = strdelim(&cp)) && *arg != '\0') { | 680 | intptr = &options->reverse_mapping_check; |
752 | if (options->num_deny_groups >= MAX_DENY_GROUPS) | 681 | goto parse_flag; |
753 | fatal("%s line %d: too many deny groups.", | ||
754 | filename, linenum); | ||
755 | options->deny_groups[options->num_deny_groups++] = xstrdup(arg); | ||
756 | } | ||
757 | break; | ||
758 | 682 | ||
759 | case sCiphers: | 683 | case sLogFacility: |
760 | arg = strdelim(&cp); | 684 | intptr = (int *) &options->log_facility; |
761 | if (!arg || *arg == '\0') | 685 | arg = strdelim(&cp); |
762 | fatal("%s line %d: Missing argument.", filename, linenum); | 686 | value = log_facility_number(arg); |
763 | if (!ciphers_valid(arg)) | 687 | if (value == (SyslogFacility) - 1) |
764 | fatal("%s line %d: Bad SSH2 cipher spec '%s'.", | 688 | fatal("%.200s line %d: unsupported log facility '%s'", |
765 | filename, linenum, arg ? arg : "<NONE>"); | 689 | filename, linenum, arg ? arg : "<NONE>"); |
766 | if (options->ciphers == NULL) | 690 | if (*intptr == -1) |
767 | options->ciphers = xstrdup(arg); | 691 | *intptr = (SyslogFacility) value; |
768 | break; | 692 | break; |
693 | |||
694 | case sLogLevel: | ||
695 | intptr = (int *) &options->log_level; | ||
696 | arg = strdelim(&cp); | ||
697 | value = log_level_number(arg); | ||
698 | if (value == (LogLevel) - 1) | ||
699 | fatal("%.200s line %d: unsupported log level '%s'", | ||
700 | filename, linenum, arg ? arg : "<NONE>"); | ||
701 | if (*intptr == -1) | ||
702 | *intptr = (LogLevel) value; | ||
703 | break; | ||
704 | |||
705 | case sAllowTcpForwarding: | ||
706 | intptr = &options->allow_tcp_forwarding; | ||
707 | goto parse_flag; | ||
708 | |||
709 | case sAllowUsers: | ||
710 | while ((arg = strdelim(&cp)) && *arg != '\0') { | ||
711 | if (options->num_allow_users >= MAX_ALLOW_USERS) | ||
712 | fatal("%s line %d: too many allow users.", | ||
713 | filename, linenum); | ||
714 | options->allow_users[options->num_allow_users++] = xstrdup(arg); | ||
715 | } | ||
716 | break; | ||
769 | 717 | ||
770 | case sMacs: | 718 | case sDenyUsers: |
771 | arg = strdelim(&cp); | 719 | while ((arg = strdelim(&cp)) && *arg != '\0') { |
772 | if (!arg || *arg == '\0') | 720 | if (options->num_deny_users >= MAX_DENY_USERS) |
773 | fatal("%s line %d: Missing argument.", filename, linenum); | 721 | fatal( "%s line %d: too many deny users.", |
774 | if (!mac_valid(arg)) | 722 | filename, linenum); |
775 | fatal("%s line %d: Bad SSH2 mac spec '%s'.", | 723 | options->deny_users[options->num_deny_users++] = xstrdup(arg); |
776 | filename, linenum, arg ? arg : "<NONE>"); | 724 | } |
777 | if (options->macs == NULL) | 725 | break; |
778 | options->macs = xstrdup(arg); | ||
779 | break; | ||
780 | 726 | ||
781 | case sProtocol: | 727 | case sAllowGroups: |
782 | intptr = &options->protocol; | 728 | while ((arg = strdelim(&cp)) && *arg != '\0') { |
783 | arg = strdelim(&cp); | 729 | if (options->num_allow_groups >= MAX_ALLOW_GROUPS) |
784 | if (!arg || *arg == '\0') | 730 | fatal("%s line %d: too many allow groups.", |
785 | fatal("%s line %d: Missing argument.", filename, linenum); | 731 | filename, linenum); |
786 | value = proto_spec(arg); | 732 | options->allow_groups[options->num_allow_groups++] = xstrdup(arg); |
787 | if (value == SSH_PROTO_UNKNOWN) | 733 | } |
788 | fatal("%s line %d: Bad protocol spec '%s'.", | 734 | break; |
789 | filename, linenum, arg ? arg : "<NONE>"); | ||
790 | if (*intptr == SSH_PROTO_UNKNOWN) | ||
791 | *intptr = value; | ||
792 | break; | ||
793 | 735 | ||
794 | case sSubsystem: | 736 | case sDenyGroups: |
795 | if (options->num_subsystems >= MAX_SUBSYSTEMS) { | 737 | while ((arg = strdelim(&cp)) && *arg != '\0') { |
796 | fatal("%s line %d: too many subsystems defined.", | 738 | if (options->num_deny_groups >= MAX_DENY_GROUPS) |
797 | filename, linenum); | 739 | fatal("%s line %d: too many deny groups.", |
798 | } | 740 | filename, linenum); |
799 | arg = strdelim(&cp); | 741 | options->deny_groups[options->num_deny_groups++] = xstrdup(arg); |
800 | if (!arg || *arg == '\0') | 742 | } |
801 | fatal("%s line %d: Missing subsystem name.", | 743 | break; |
802 | filename, linenum); | ||
803 | for (i = 0; i < options->num_subsystems; i++) | ||
804 | if (strcmp(arg, options->subsystem_name[i]) == 0) | ||
805 | fatal("%s line %d: Subsystem '%s' already defined.", | ||
806 | filename, linenum, arg); | ||
807 | options->subsystem_name[options->num_subsystems] = xstrdup(arg); | ||
808 | arg = strdelim(&cp); | ||
809 | if (!arg || *arg == '\0') | ||
810 | fatal("%s line %d: Missing subsystem command.", | ||
811 | filename, linenum); | ||
812 | options->subsystem_command[options->num_subsystems] = xstrdup(arg); | ||
813 | options->num_subsystems++; | ||
814 | break; | ||
815 | 744 | ||
816 | case sMaxStartups: | 745 | case sCiphers: |
817 | arg = strdelim(&cp); | 746 | arg = strdelim(&cp); |
818 | if (!arg || *arg == '\0') | 747 | if (!arg || *arg == '\0') |
819 | fatal("%s line %d: Missing MaxStartups spec.", | 748 | fatal("%s line %d: Missing argument.", filename, linenum); |
820 | filename, linenum); | 749 | if (!ciphers_valid(arg)) |
821 | if ((n = sscanf(arg, "%d:%d:%d", | 750 | fatal("%s line %d: Bad SSH2 cipher spec '%s'.", |
822 | &options->max_startups_begin, | 751 | filename, linenum, arg ? arg : "<NONE>"); |
823 | &options->max_startups_rate, | 752 | if (options->ciphers == NULL) |
824 | &options->max_startups)) == 3) { | 753 | options->ciphers = xstrdup(arg); |
825 | if (options->max_startups_begin > | 754 | break; |
826 | options->max_startups || | 755 | |
827 | options->max_startups_rate > 100 || | 756 | case sMacs: |
828 | options->max_startups_rate < 1) | 757 | arg = strdelim(&cp); |
829 | fatal("%s line %d: Illegal MaxStartups spec.", | 758 | if (!arg || *arg == '\0') |
830 | filename, linenum); | 759 | fatal("%s line %d: Missing argument.", filename, linenum); |
831 | } else if (n != 1) | 760 | if (!mac_valid(arg)) |
761 | fatal("%s line %d: Bad SSH2 mac spec '%s'.", | ||
762 | filename, linenum, arg ? arg : "<NONE>"); | ||
763 | if (options->macs == NULL) | ||
764 | options->macs = xstrdup(arg); | ||
765 | break; | ||
766 | |||
767 | case sProtocol: | ||
768 | intptr = &options->protocol; | ||
769 | arg = strdelim(&cp); | ||
770 | if (!arg || *arg == '\0') | ||
771 | fatal("%s line %d: Missing argument.", filename, linenum); | ||
772 | value = proto_spec(arg); | ||
773 | if (value == SSH_PROTO_UNKNOWN) | ||
774 | fatal("%s line %d: Bad protocol spec '%s'.", | ||
775 | filename, linenum, arg ? arg : "<NONE>"); | ||
776 | if (*intptr == SSH_PROTO_UNKNOWN) | ||
777 | *intptr = value; | ||
778 | break; | ||
779 | |||
780 | case sSubsystem: | ||
781 | if (options->num_subsystems >= MAX_SUBSYSTEMS) { | ||
782 | fatal("%s line %d: too many subsystems defined.", | ||
783 | filename, linenum); | ||
784 | } | ||
785 | arg = strdelim(&cp); | ||
786 | if (!arg || *arg == '\0') | ||
787 | fatal("%s line %d: Missing subsystem name.", | ||
788 | filename, linenum); | ||
789 | for (i = 0; i < options->num_subsystems; i++) | ||
790 | if (strcmp(arg, options->subsystem_name[i]) == 0) | ||
791 | fatal("%s line %d: Subsystem '%s' already defined.", | ||
792 | filename, linenum, arg); | ||
793 | options->subsystem_name[options->num_subsystems] = xstrdup(arg); | ||
794 | arg = strdelim(&cp); | ||
795 | if (!arg || *arg == '\0') | ||
796 | fatal("%s line %d: Missing subsystem command.", | ||
797 | filename, linenum); | ||
798 | options->subsystem_command[options->num_subsystems] = xstrdup(arg); | ||
799 | options->num_subsystems++; | ||
800 | break; | ||
801 | |||
802 | case sMaxStartups: | ||
803 | arg = strdelim(&cp); | ||
804 | if (!arg || *arg == '\0') | ||
805 | fatal("%s line %d: Missing MaxStartups spec.", | ||
806 | filename, linenum); | ||
807 | if ((n = sscanf(arg, "%d:%d:%d", | ||
808 | &options->max_startups_begin, | ||
809 | &options->max_startups_rate, | ||
810 | &options->max_startups)) == 3) { | ||
811 | if (options->max_startups_begin > | ||
812 | options->max_startups || | ||
813 | options->max_startups_rate > 100 || | ||
814 | options->max_startups_rate < 1) | ||
832 | fatal("%s line %d: Illegal MaxStartups spec.", | 815 | fatal("%s line %d: Illegal MaxStartups spec.", |
833 | filename, linenum); | 816 | filename, linenum); |
834 | else | 817 | } else if (n != 1) |
835 | options->max_startups = options->max_startups_begin; | 818 | fatal("%s line %d: Illegal MaxStartups spec.", |
836 | break; | 819 | filename, linenum); |
820 | else | ||
821 | options->max_startups = options->max_startups_begin; | ||
822 | break; | ||
823 | |||
824 | case sBanner: | ||
825 | charptr = &options->banner; | ||
826 | goto parse_filename; | ||
827 | /* | ||
828 | * These options can contain %X options expanded at | ||
829 | * connect time, so that you can specify paths like: | ||
830 | * | ||
831 | * AuthorizedKeysFile /etc/ssh_keys/%u | ||
832 | */ | ||
833 | case sAuthorizedKeysFile: | ||
834 | case sAuthorizedKeysFile2: | ||
835 | charptr = (opcode == sAuthorizedKeysFile ) ? | ||
836 | &options->authorized_keys_file : | ||
837 | &options->authorized_keys_file2; | ||
838 | goto parse_filename; | ||
839 | |||
840 | case sClientAliveInterval: | ||
841 | intptr = &options->client_alive_interval; | ||
842 | goto parse_time; | ||
843 | |||
844 | case sClientAliveCountMax: | ||
845 | intptr = &options->client_alive_count_max; | ||
846 | goto parse_int; | ||
847 | |||
848 | case sDeprecated: | ||
849 | log("%s line %d: Deprecated option %s", | ||
850 | filename, linenum, arg); | ||
851 | while (arg) | ||
852 | arg = strdelim(&cp); | ||
853 | break; | ||
854 | |||
855 | default: | ||
856 | fatal("%s line %d: Missing handler for opcode %s (%d)", | ||
857 | filename, linenum, arg, opcode); | ||
858 | } | ||
859 | if ((arg = strdelim(&cp)) != NULL && *arg != '\0') | ||
860 | fatal("%s line %d: garbage at end of line; \"%.200s\".", | ||
861 | filename, linenum, arg); | ||
862 | return 0; | ||
863 | } | ||
837 | 864 | ||
838 | case sBanner: | 865 | /* Reads the server configuration file. */ |
839 | charptr = &options->banner; | ||
840 | goto parse_filename; | ||
841 | /* | ||
842 | * These options can contain %X options expanded at | ||
843 | * connect time, so that you can specify paths like: | ||
844 | * | ||
845 | * AuthorizedKeysFile /etc/ssh_keys/%u | ||
846 | */ | ||
847 | case sAuthorizedKeysFile: | ||
848 | case sAuthorizedKeysFile2: | ||
849 | charptr = (opcode == sAuthorizedKeysFile ) ? | ||
850 | &options->authorized_keys_file : | ||
851 | &options->authorized_keys_file2; | ||
852 | goto parse_filename; | ||
853 | |||
854 | case sClientAliveInterval: | ||
855 | intptr = &options->client_alive_interval; | ||
856 | goto parse_time; | ||
857 | |||
858 | case sClientAliveCountMax: | ||
859 | intptr = &options->client_alive_count_max; | ||
860 | goto parse_int; | ||
861 | |||
862 | case sDeprecated: | ||
863 | log("%s line %d: Deprecated option %s", | ||
864 | filename, linenum, arg); | ||
865 | while (arg) | ||
866 | arg = strdelim(&cp); | ||
867 | break; | ||
868 | 866 | ||
869 | default: | 867 | void |
870 | fatal("%s line %d: Missing handler for opcode %s (%d)", | 868 | read_server_config(ServerOptions *options, const char *filename) |
871 | filename, linenum, arg, opcode); | 869 | { |
872 | } | 870 | FILE *f; |
873 | if ((arg = strdelim(&cp)) != NULL && *arg != '\0') | 871 | char line[1024]; |
874 | fatal("%s line %d: garbage at end of line; \"%.200s\".", | 872 | int linenum; |
875 | filename, linenum, arg); | 873 | int bad_options = 0; |
874 | |||
875 | f = fopen(filename, "r"); | ||
876 | if (!f) { | ||
877 | perror(filename); | ||
878 | exit(1); | ||
879 | } | ||
880 | linenum = 0; | ||
881 | while (fgets(line, sizeof(line), f)) { | ||
882 | /* Update line number counter. */ | ||
883 | linenum++; | ||
884 | if (process_server_config_line(options, line, filename, linenum) != 0) | ||
885 | bad_options++; | ||
876 | } | 886 | } |
877 | fclose(f); | 887 | fclose(f); |
878 | if (bad_options > 0) | 888 | if (bad_options > 0) |