summaryrefslogtreecommitdiff
path: root/servconf.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-12-06 18:22:17 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-12-06 18:22:17 +0000
commitade03f6bad77faf80441396eb41134489454e1c1 (patch)
tree2d49b6124b798fba1a52482a228017fde6f7118b /servconf.c
parent9eab262f1ce2e54f7e5d2b75477a606c33e8bc0a (diff)
- markus@cvs.openbsd.org 2001/12/06 13:30:06
[servconf.c servconf.h sshd.8 sshd.c] add -o to sshd, too. ok deraadt@ - (bal) Minor white space fix up in servconf.c
Diffstat (limited to 'servconf.c')
-rw-r--r--servconf.c888
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"
13RCSID("$OpenBSD: servconf.c,v 1.93 2001/12/05 10:06:12 deraadt Exp $"); 13RCSID("$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. */ 395int
396 396process_server_config_line(ServerOptions *options, char *line,
397void 397 const char *filename, int linenum)
398read_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;
459parse_int: 445parse_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;
471parse_time: 457parse_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];
530parse_filename: 516parse_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;
573parse_flag: 559parse_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: 867void
870 fatal("%s line %d: Missing handler for opcode %s (%d)", 868read_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)