diff options
author | dtucker@openbsd.org <dtucker@openbsd.org> | 2015-04-29 03:48:56 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2015-04-29 18:20:32 +1000 |
commit | 531a57a3893f9fcd4aaaba8c312b612bbbcc021e (patch) | |
tree | 5fa3b241eaaf4e19653aee6b73926218a2f887e3 /servconf.c | |
parent | c1d5bcf1aaf1209af02f79e48ba1cbc76a87b56f (diff) |
upstream commit
Allow ListenAddress, Port and AddressFamily in any
order. bz#68, ok djm@, jmc@ (for the man page bit).
Diffstat (limited to 'servconf.c')
-rw-r--r-- | servconf.c | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/servconf.c b/servconf.c index 8d56a309b..29457b833 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $OpenBSD: servconf.c,v 1.265 2015/04/27 21:42:48 djm Exp $ */ | 2 | /* $OpenBSD: servconf.c,v 1.266 2015/04/29 03:48:56 dtucker Exp $ */ |
3 | /* | 3 | /* |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
5 | * All rights reserved | 5 | * All rights reserved |
@@ -78,6 +78,8 @@ initialize_server_options(ServerOptions *options) | |||
78 | /* Standard Options */ | 78 | /* Standard Options */ |
79 | options->num_ports = 0; | 79 | options->num_ports = 0; |
80 | options->ports_from_cmdline = 0; | 80 | options->ports_from_cmdline = 0; |
81 | options->queued_listen_addrs = NULL; | ||
82 | options->num_queued_listens = 0; | ||
81 | options->listen_addrs = NULL; | 83 | options->listen_addrs = NULL; |
82 | options->address_family = -1; | 84 | options->address_family = -1; |
83 | options->num_host_key_files = 0; | 85 | options->num_host_key_files = 0; |
@@ -205,6 +207,8 @@ fill_default_server_options(ServerOptions *options) | |||
205 | /* No certificates by default */ | 207 | /* No certificates by default */ |
206 | if (options->num_ports == 0) | 208 | if (options->num_ports == 0) |
207 | options->ports[options->num_ports++] = SSH_DEFAULT_PORT; | 209 | options->ports[options->num_ports++] = SSH_DEFAULT_PORT; |
210 | if (options->address_family == -1) | ||
211 | options->address_family = AF_UNSPEC; | ||
208 | if (options->listen_addrs == NULL) | 212 | if (options->listen_addrs == NULL) |
209 | add_listen_addr(options, NULL, 0); | 213 | add_listen_addr(options, NULL, 0); |
210 | if (options->pid_file == NULL) | 214 | if (options->pid_file == NULL) |
@@ -591,10 +595,6 @@ add_listen_addr(ServerOptions *options, char *addr, int port) | |||
591 | { | 595 | { |
592 | u_int i; | 596 | u_int i; |
593 | 597 | ||
594 | if (options->num_ports == 0) | ||
595 | options->ports[options->num_ports++] = SSH_DEFAULT_PORT; | ||
596 | if (options->address_family == -1) | ||
597 | options->address_family = AF_UNSPEC; | ||
598 | if (port == 0) | 598 | if (port == 0) |
599 | for (i = 0; i < options->num_ports; i++) | 599 | for (i = 0; i < options->num_ports; i++) |
600 | add_one_listen_addr(options, addr, options->ports[i]); | 600 | add_one_listen_addr(options, addr, options->ports[i]); |
@@ -624,6 +624,51 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port) | |||
624 | options->listen_addrs = aitop; | 624 | options->listen_addrs = aitop; |
625 | } | 625 | } |
626 | 626 | ||
627 | /* | ||
628 | * Queue a ListenAddress to be processed once we have all of the Ports | ||
629 | * and AddressFamily options. | ||
630 | */ | ||
631 | static void | ||
632 | queue_listen_addr(ServerOptions *options, char *addr, int port) | ||
633 | { | ||
634 | options->queued_listen_addrs = xreallocarray( | ||
635 | options->queued_listen_addrs, options->num_queued_listens + 1, | ||
636 | sizeof(addr)); | ||
637 | options->queued_listen_ports = xreallocarray( | ||
638 | options->queued_listen_ports, options->num_queued_listens + 1, | ||
639 | sizeof(port)); | ||
640 | options->queued_listen_addrs[options->num_queued_listens] = | ||
641 | xstrdup(addr); | ||
642 | options->queued_listen_ports[options->num_queued_listens] = port; | ||
643 | options->num_queued_listens++; | ||
644 | } | ||
645 | |||
646 | /* | ||
647 | * Process queued (text) ListenAddress entries. | ||
648 | */ | ||
649 | static void | ||
650 | process_queued_listen_addrs(ServerOptions *options) | ||
651 | { | ||
652 | u_int i; | ||
653 | |||
654 | if (options->num_ports == 0) | ||
655 | options->ports[options->num_ports++] = SSH_DEFAULT_PORT; | ||
656 | if (options->address_family == -1) | ||
657 | options->address_family = AF_UNSPEC; | ||
658 | |||
659 | for (i = 0; i < options->num_queued_listens; i++) { | ||
660 | add_listen_addr(options, options->queued_listen_addrs[i], | ||
661 | options->queued_listen_ports[i]); | ||
662 | free(options->queued_listen_addrs[i]); | ||
663 | options->queued_listen_addrs[i] = NULL; | ||
664 | } | ||
665 | free(options->queued_listen_addrs); | ||
666 | options->queued_listen_addrs = NULL; | ||
667 | free(options->queued_listen_ports); | ||
668 | options->queued_listen_ports = NULL; | ||
669 | options->num_queued_listens = 0; | ||
670 | } | ||
671 | |||
627 | struct connection_info * | 672 | struct connection_info * |
628 | get_connection_info(int populate, int use_dns) | 673 | get_connection_info(int populate, int use_dns) |
629 | { | 674 | { |
@@ -940,9 +985,6 @@ process_server_config_line(ServerOptions *options, char *line, | |||
940 | /* ignore ports from configfile if cmdline specifies ports */ | 985 | /* ignore ports from configfile if cmdline specifies ports */ |
941 | if (options->ports_from_cmdline) | 986 | if (options->ports_from_cmdline) |
942 | return 0; | 987 | return 0; |
943 | if (options->listen_addrs != NULL) | ||
944 | fatal("%s line %d: ports must be specified before " | ||
945 | "ListenAddress.", filename, linenum); | ||
946 | if (options->num_ports >= MAX_PORTS) | 988 | if (options->num_ports >= MAX_PORTS) |
947 | fatal("%s line %d: too many ports.", | 989 | fatal("%s line %d: too many ports.", |
948 | filename, linenum); | 990 | filename, linenum); |
@@ -994,7 +1036,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
994 | /* check for bare IPv6 address: no "[]" and 2 or more ":" */ | 1036 | /* check for bare IPv6 address: no "[]" and 2 or more ":" */ |
995 | if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL | 1037 | if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL |
996 | && strchr(p+1, ':') != NULL) { | 1038 | && strchr(p+1, ':') != NULL) { |
997 | add_listen_addr(options, arg, 0); | 1039 | queue_listen_addr(options, arg, 0); |
998 | break; | 1040 | break; |
999 | } | 1041 | } |
1000 | p = hpdelim(&arg); | 1042 | p = hpdelim(&arg); |
@@ -1007,16 +1049,13 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1007 | else if ((port = a2port(arg)) <= 0) | 1049 | else if ((port = a2port(arg)) <= 0) |
1008 | fatal("%s line %d: bad port number", filename, linenum); | 1050 | fatal("%s line %d: bad port number", filename, linenum); |
1009 | 1051 | ||
1010 | add_listen_addr(options, p, port); | 1052 | queue_listen_addr(options, p, port); |
1011 | 1053 | ||
1012 | break; | 1054 | break; |
1013 | 1055 | ||
1014 | case sAddressFamily: | 1056 | case sAddressFamily: |
1015 | intptr = &options->address_family; | 1057 | intptr = &options->address_family; |
1016 | multistate_ptr = multistate_addressfamily; | 1058 | multistate_ptr = multistate_addressfamily; |
1017 | if (options->listen_addrs != NULL) | ||
1018 | fatal("%s line %d: address family must be specified " | ||
1019 | "before ListenAddress.", filename, linenum); | ||
1020 | parse_multistate: | 1059 | parse_multistate: |
1021 | arg = strdelim(&cp); | 1060 | arg = strdelim(&cp); |
1022 | if (!arg || *arg == '\0') | 1061 | if (!arg || *arg == '\0') |
@@ -1951,6 +1990,7 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, | |||
1951 | if (bad_options > 0) | 1990 | if (bad_options > 0) |
1952 | fatal("%s: terminating, %d bad configuration options", | 1991 | fatal("%s: terminating, %d bad configuration options", |
1953 | filename, bad_options); | 1992 | filename, bad_options); |
1993 | process_queued_listen_addrs(options); | ||
1954 | } | 1994 | } |
1955 | 1995 | ||
1956 | static const char * | 1996 | static const char * |