summaryrefslogtreecommitdiff
path: root/servconf.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2018-04-03 08:20:28 +0100
committerColin Watson <cjwatson@debian.org>2018-04-03 08:20:28 +0100
commited6ae9c1a014a08ff5db3d768f01f2e427eeb476 (patch)
tree601025e307745d351946c01ab13f419ddb6dae29 /servconf.c
parent62f54f20bf351468e0124f63cc2902ee40d9b0e9 (diff)
parenta0349a1cc4a18967ad1dbff5389bcdf9da098814 (diff)
Import openssh_7.7p1.orig.tar.gz
Diffstat (limited to 'servconf.c')
-rw-r--r--servconf.c567
1 files changed, 361 insertions, 206 deletions
diff --git a/servconf.c b/servconf.c
index 2c321a4ad..0f0d09068 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.312 2017/10/02 19:33:20 djm Exp $ */ 2/* $OpenBSD: servconf.c,v 1.326 2018/03/01 20:32:16 markus 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
@@ -15,10 +15,16 @@
15 15
16#include <sys/types.h> 16#include <sys/types.h>
17#include <sys/socket.h> 17#include <sys/socket.h>
18#ifdef HAVE_SYS_SYSCTL_H
19#include <sys/sysctl.h>
20#endif
18 21
19#include <netinet/in.h> 22#include <netinet/in.h>
20#include <netinet/in_systm.h> 23#include <netinet/in_systm.h>
21#include <netinet/ip.h> 24#include <netinet/ip.h>
25#ifdef HAVE_NET_ROUTE_H
26#include <net/route.h>
27#endif
22 28
23#include <ctype.h> 29#include <ctype.h>
24#include <netdb.h> 30#include <netdb.h>
@@ -58,8 +64,10 @@
58#include "myproposal.h" 64#include "myproposal.h"
59#include "digest.h" 65#include "digest.h"
60 66
61static void add_listen_addr(ServerOptions *, char *, int); 67static void add_listen_addr(ServerOptions *, const char *,
62static void add_one_listen_addr(ServerOptions *, char *, int); 68 const char *, int);
69static void add_one_listen_addr(ServerOptions *, const char *,
70 const char *, int);
63 71
64/* Use of privilege separation or not */ 72/* Use of privilege separation or not */
65extern int use_privsep; 73extern int use_privsep;
@@ -81,7 +89,9 @@ initialize_server_options(ServerOptions *options)
81 options->queued_listen_addrs = NULL; 89 options->queued_listen_addrs = NULL;
82 options->num_queued_listens = 0; 90 options->num_queued_listens = 0;
83 options->listen_addrs = NULL; 91 options->listen_addrs = NULL;
92 options->num_listen_addrs = 0;
84 options->address_family = -1; 93 options->address_family = -1;
94 options->routing_domain = NULL;
85 options->num_host_key_files = 0; 95 options->num_host_key_files = 0;
86 options->num_host_cert_files = 0; 96 options->num_host_cert_files = 0;
87 options->host_key_agent = NULL; 97 options->host_key_agent = NULL;
@@ -188,10 +198,45 @@ assemble_algorithms(ServerOptions *o)
188 fatal("kex_assemble_names failed"); 198 fatal("kex_assemble_names failed");
189} 199}
190 200
201static void
202array_append(const char *file, const int line, const char *directive,
203 char ***array, u_int *lp, const char *s)
204{
205
206 if (*lp >= INT_MAX)
207 fatal("%s line %d: Too many %s entries", file, line, directive);
208
209 *array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
210 (*array)[*lp] = xstrdup(s);
211 (*lp)++;
212}
213
214void
215servconf_add_hostkey(const char *file, const int line,
216 ServerOptions *options, const char *path)
217{
218 char *apath = derelativise_path(path);
219
220 array_append(file, line, "HostKey",
221 &options->host_key_files, &options->num_host_key_files, apath);
222 free(apath);
223}
224
225void
226servconf_add_hostcert(const char *file, const int line,
227 ServerOptions *options, const char *path)
228{
229 char *apath = derelativise_path(path);
230
231 array_append(file, line, "HostCertificate",
232 &options->host_cert_files, &options->num_host_cert_files, apath);
233 free(apath);
234}
235
191void 236void
192fill_default_server_options(ServerOptions *options) 237fill_default_server_options(ServerOptions *options)
193{ 238{
194 int i; 239 u_int i;
195 240
196 /* Portable-specific options */ 241 /* Portable-specific options */
197 if (options->use_pam == -1) 242 if (options->use_pam == -1)
@@ -200,16 +245,18 @@ fill_default_server_options(ServerOptions *options)
200 /* Standard Options */ 245 /* Standard Options */
201 if (options->num_host_key_files == 0) { 246 if (options->num_host_key_files == 0) {
202 /* fill default hostkeys for protocols */ 247 /* fill default hostkeys for protocols */
203 options->host_key_files[options->num_host_key_files++] = 248 servconf_add_hostkey("[default]", 0, options,
204 _PATH_HOST_RSA_KEY_FILE; 249 _PATH_HOST_RSA_KEY_FILE);
205 options->host_key_files[options->num_host_key_files++] =
206 _PATH_HOST_DSA_KEY_FILE;
207#ifdef OPENSSL_HAS_ECC 250#ifdef OPENSSL_HAS_ECC
208 options->host_key_files[options->num_host_key_files++] = 251 servconf_add_hostkey("[default]", 0, options,
209 _PATH_HOST_ECDSA_KEY_FILE; 252 _PATH_HOST_ECDSA_KEY_FILE);
210#endif 253#endif
211 options->host_key_files[options->num_host_key_files++] = 254 servconf_add_hostkey("[default]", 0, options,
212 _PATH_HOST_ED25519_KEY_FILE; 255 _PATH_HOST_ED25519_KEY_FILE);
256#ifdef WITH_XMSS
257 servconf_add_hostkey("[default]", 0, options,
258 _PATH_HOST_XMSS_KEY_FILE);
259#endif /* WITH_XMSS */
213 } 260 }
214 /* No certificates by default */ 261 /* No certificates by default */
215 if (options->num_ports == 0) 262 if (options->num_ports == 0)
@@ -217,7 +264,7 @@ fill_default_server_options(ServerOptions *options)
217 if (options->address_family == -1) 264 if (options->address_family == -1)
218 options->address_family = AF_UNSPEC; 265 options->address_family = AF_UNSPEC;
219 if (options->listen_addrs == NULL) 266 if (options->listen_addrs == NULL)
220 add_listen_addr(options, NULL, 0); 267 add_listen_addr(options, NULL, NULL, 0);
221 if (options->pid_file == NULL) 268 if (options->pid_file == NULL)
222 options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE); 269 options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
223 if (options->login_grace_time == -1) 270 if (options->login_grace_time == -1)
@@ -313,10 +360,14 @@ fill_default_server_options(ServerOptions *options)
313 if (options->client_alive_count_max == -1) 360 if (options->client_alive_count_max == -1)
314 options->client_alive_count_max = 3; 361 options->client_alive_count_max = 3;
315 if (options->num_authkeys_files == 0) { 362 if (options->num_authkeys_files == 0) {
316 options->authorized_keys_files[options->num_authkeys_files++] = 363 array_append("[default]", 0, "AuthorizedKeysFiles",
317 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); 364 &options->authorized_keys_files,
318 options->authorized_keys_files[options->num_authkeys_files++] = 365 &options->num_authkeys_files,
319 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); 366 _PATH_SSH_USER_PERMITTED_KEYS);
367 array_append("[default]", 0, "AuthorizedKeysFiles",
368 &options->authorized_keys_files,
369 &options->num_authkeys_files,
370 _PATH_SSH_USER_PERMITTED_KEYS2);
320 } 371 }
321 if (options->permit_tun == -1) 372 if (options->permit_tun == -1)
322 options->permit_tun = SSH_TUNMODE_NO; 373 options->permit_tun = SSH_TUNMODE_NO;
@@ -358,6 +409,7 @@ fill_default_server_options(ServerOptions *options)
358 CLEAR_ON_NONE(options->authorized_principals_file); 409 CLEAR_ON_NONE(options->authorized_principals_file);
359 CLEAR_ON_NONE(options->adm_forced_command); 410 CLEAR_ON_NONE(options->adm_forced_command);
360 CLEAR_ON_NONE(options->chroot_directory); 411 CLEAR_ON_NONE(options->chroot_directory);
412 CLEAR_ON_NONE(options->routing_domain);
361 for (i = 0; i < options->num_host_key_files; i++) 413 for (i = 0; i < options->num_host_key_files; i++)
362 CLEAR_ON_NONE(options->host_key_files[i]); 414 CLEAR_ON_NONE(options->host_key_files[i]);
363 for (i = 0; i < options->num_host_cert_files; i++) 415 for (i = 0; i < options->num_host_cert_files; i++)
@@ -393,8 +445,7 @@ typedef enum {
393 sPermitRootLogin, sLogFacility, sLogLevel, 445 sPermitRootLogin, sLogFacility, sLogLevel,
394 sRhostsRSAAuthentication, sRSAAuthentication, 446 sRhostsRSAAuthentication, sRSAAuthentication,
395 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 447 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
396 sKerberosGetAFSToken, 448 sKerberosGetAFSToken, sChallengeResponseAuthentication,
397 sKerberosTgtPassing, sChallengeResponseAuthentication,
398 sPasswordAuthentication, sKbdInteractiveAuthentication, 449 sPasswordAuthentication, sKbdInteractiveAuthentication,
399 sListenAddress, sAddressFamily, 450 sListenAddress, sAddressFamily,
400 sPrintMotd, sPrintLastLog, sIgnoreRhosts, 451 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
@@ -421,7 +472,7 @@ typedef enum {
421 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, 472 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
422 sStreamLocalBindMask, sStreamLocalBindUnlink, 473 sStreamLocalBindMask, sStreamLocalBindUnlink,
423 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, 474 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
424 sExposeAuthInfo, 475 sExposeAuthInfo, sRDomain,
425 sDeprecated, sIgnore, sUnsupported 476 sDeprecated, sIgnore, sUnsupported
426} ServerOpCodes; 477} ServerOpCodes;
427 478
@@ -566,6 +617,7 @@ static struct {
566 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, 617 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
567 { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, 618 { "disableforwarding", sDisableForwarding, SSHCFG_ALL },
568 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, 619 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
620 { "rdomain", sRDomain, SSHCFG_ALL },
569 { NULL, sBadOption, 0 } 621 { NULL, sBadOption, 0 }
570}; 622};
571 623
@@ -619,23 +671,51 @@ derelativise_path(const char *path)
619} 671}
620 672
621static void 673static void
622add_listen_addr(ServerOptions *options, char *addr, int port) 674add_listen_addr(ServerOptions *options, const char *addr,
675 const char *rdomain, int port)
623{ 676{
624 u_int i; 677 u_int i;
625 678
626 if (port == 0) 679 if (port > 0)
627 for (i = 0; i < options->num_ports; i++) 680 add_one_listen_addr(options, addr, rdomain, port);
628 add_one_listen_addr(options, addr, options->ports[i]); 681 else {
629 else 682 for (i = 0; i < options->num_ports; i++) {
630 add_one_listen_addr(options, addr, port); 683 add_one_listen_addr(options, addr, rdomain,
684 options->ports[i]);
685 }
686 }
631} 687}
632 688
633static void 689static void
634add_one_listen_addr(ServerOptions *options, char *addr, int port) 690add_one_listen_addr(ServerOptions *options, const char *addr,
691 const char *rdomain, int port)
635{ 692{
636 struct addrinfo hints, *ai, *aitop; 693 struct addrinfo hints, *ai, *aitop;
637 char strport[NI_MAXSERV]; 694 char strport[NI_MAXSERV];
638 int gaierr; 695 int gaierr;
696 u_int i;
697
698 /* Find listen_addrs entry for this rdomain */
699 for (i = 0; i < options->num_listen_addrs; i++) {
700 if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
701 break;
702 if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
703 continue;
704 if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
705 break;
706 }
707 if (i >= options->num_listen_addrs) {
708 /* No entry for this rdomain; allocate one */
709 if (i >= INT_MAX)
710 fatal("%s: too many listen addresses", __func__);
711 options->listen_addrs = xrecallocarray(options->listen_addrs,
712 options->num_listen_addrs, options->num_listen_addrs + 1,
713 sizeof(*options->listen_addrs));
714 i = options->num_listen_addrs++;
715 if (rdomain != NULL)
716 options->listen_addrs[i].rdomain = xstrdup(rdomain);
717 }
718 /* options->listen_addrs[i] points to the addresses for this rdomain */
639 719
640 memset(&hints, 0, sizeof(hints)); 720 memset(&hints, 0, sizeof(hints));
641 hints.ai_family = options->address_family; 721 hints.ai_family = options->address_family;
@@ -648,8 +728,44 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
648 ssh_gai_strerror(gaierr)); 728 ssh_gai_strerror(gaierr));
649 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 729 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
650 ; 730 ;
651 ai->ai_next = options->listen_addrs; 731 ai->ai_next = options->listen_addrs[i].addrs;
652 options->listen_addrs = aitop; 732 options->listen_addrs[i].addrs = aitop;
733}
734
735/* Returns nonzero if the routing domain name is valid */
736static int
737valid_rdomain(const char *name)
738{
739#if defined(HAVE_SYS_VALID_RDOMAIN)
740 return sys_valid_rdomain(name);
741#elif defined(__OpenBSD__)
742 const char *errstr;
743 long long num;
744 struct rt_tableinfo info;
745 int mib[6];
746 size_t miblen = sizeof(mib);
747
748 if (name == NULL)
749 return 1;
750
751 num = strtonum(name, 0, 255, &errstr);
752 if (errstr != NULL)
753 return 0;
754
755 /* Check whether the table actually exists */
756 memset(mib, 0, sizeof(mib));
757 mib[0] = CTL_NET;
758 mib[1] = PF_ROUTE;
759 mib[4] = NET_RT_TABLE;
760 mib[5] = (int)num;
761 if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
762 return 0;
763
764 return 1;
765#else /* defined(__OpenBSD__) */
766 error("Routing domains are not supported on this platform");
767 return 0;
768#endif
653} 769}
654 770
655/* 771/*
@@ -657,18 +773,19 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
657 * and AddressFamily options. 773 * and AddressFamily options.
658 */ 774 */
659static void 775static void
660queue_listen_addr(ServerOptions *options, char *addr, int port) 776queue_listen_addr(ServerOptions *options, const char *addr,
777 const char *rdomain, int port)
661{ 778{
662 options->queued_listen_addrs = xreallocarray( 779 struct queued_listenaddr *qla;
663 options->queued_listen_addrs, options->num_queued_listens + 1, 780
664 sizeof(addr)); 781 options->queued_listen_addrs = xrecallocarray(
665 options->queued_listen_ports = xreallocarray( 782 options->queued_listen_addrs,
666 options->queued_listen_ports, options->num_queued_listens + 1, 783 options->num_queued_listens, options->num_queued_listens + 1,
667 sizeof(port)); 784 sizeof(*options->queued_listen_addrs));
668 options->queued_listen_addrs[options->num_queued_listens] = 785 qla = &options->queued_listen_addrs[options->num_queued_listens++];
669 xstrdup(addr); 786 qla->addr = xstrdup(addr);
670 options->queued_listen_ports[options->num_queued_listens] = port; 787 qla->port = port;
671 options->num_queued_listens++; 788 qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
672} 789}
673 790
674/* 791/*
@@ -678,6 +795,7 @@ static void
678process_queued_listen_addrs(ServerOptions *options) 795process_queued_listen_addrs(ServerOptions *options)
679{ 796{
680 u_int i; 797 u_int i;
798 struct queued_listenaddr *qla;
681 799
682 if (options->num_ports == 0) 800 if (options->num_ports == 0)
683 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 801 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
@@ -685,15 +803,13 @@ process_queued_listen_addrs(ServerOptions *options)
685 options->address_family = AF_UNSPEC; 803 options->address_family = AF_UNSPEC;
686 804
687 for (i = 0; i < options->num_queued_listens; i++) { 805 for (i = 0; i < options->num_queued_listens; i++) {
688 add_listen_addr(options, options->queued_listen_addrs[i], 806 qla = &options->queued_listen_addrs[i];
689 options->queued_listen_ports[i]); 807 add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
690 free(options->queued_listen_addrs[i]); 808 free(qla->addr);
691 options->queued_listen_addrs[i] = NULL; 809 free(qla->rdomain);
692 } 810 }
693 free(options->queued_listen_addrs); 811 free(options->queued_listen_addrs);
694 options->queued_listen_addrs = NULL; 812 options->queued_listen_addrs = NULL;
695 free(options->queued_listen_ports);
696 options->queued_listen_ports = NULL;
697 options->num_queued_listens = 0; 813 options->num_queued_listens = 0;
698} 814}
699 815
@@ -747,6 +863,7 @@ get_connection_info(int populate, int use_dns)
747 ci.address = ssh_remote_ipaddr(ssh); 863 ci.address = ssh_remote_ipaddr(ssh);
748 ci.laddress = ssh_local_ipaddr(ssh); 864 ci.laddress = ssh_local_ipaddr(ssh);
749 ci.lport = ssh_local_port(ssh); 865 ci.lport = ssh_local_port(ssh);
866 ci.rdomain = ssh_packet_rdomain_in(ssh);
750 return &ci; 867 return &ci;
751} 868}
752 869
@@ -811,6 +928,13 @@ out:
811 return result; 928 return result;
812} 929}
813 930
931static void
932match_test_missing_fatal(const char *criteria, const char *attrib)
933{
934 fatal("'Match %s' in configuration but '%s' not in connection "
935 "test specification.", criteria, attrib);
936}
937
814/* 938/*
815 * All of the attributes on a single Match line are ANDed together, so we need 939 * All of the attributes on a single Match line are ANDed together, so we need
816 * to check every attribute and set the result to zero if any attribute does 940 * to check every attribute and set the result to zero if any attribute does
@@ -848,20 +972,24 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
848 return -1; 972 return -1;
849 } 973 }
850 if (strcasecmp(attrib, "user") == 0) { 974 if (strcasecmp(attrib, "user") == 0) {
851 if (ci == NULL || ci->user == NULL) { 975 if (ci == NULL) {
852 result = 0; 976 result = 0;
853 continue; 977 continue;
854 } 978 }
979 if (ci->user == NULL)
980 match_test_missing_fatal("User", "user");
855 if (match_pattern_list(ci->user, arg, 0) != 1) 981 if (match_pattern_list(ci->user, arg, 0) != 1)
856 result = 0; 982 result = 0;
857 else 983 else
858 debug("user %.100s matched 'User %.100s' at " 984 debug("user %.100s matched 'User %.100s' at "
859 "line %d", ci->user, arg, line); 985 "line %d", ci->user, arg, line);
860 } else if (strcasecmp(attrib, "group") == 0) { 986 } else if (strcasecmp(attrib, "group") == 0) {
861 if (ci == NULL || ci->user == NULL) { 987 if (ci == NULL) {
862 result = 0; 988 result = 0;
863 continue; 989 continue;
864 } 990 }
991 if (ci->user == NULL)
992 match_test_missing_fatal("Group", "user");
865 switch (match_cfg_line_group(arg, line, ci->user)) { 993 switch (match_cfg_line_group(arg, line, ci->user)) {
866 case -1: 994 case -1:
867 return -1; 995 return -1;
@@ -869,20 +997,24 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
869 result = 0; 997 result = 0;
870 } 998 }
871 } else if (strcasecmp(attrib, "host") == 0) { 999 } else if (strcasecmp(attrib, "host") == 0) {
872 if (ci == NULL || ci->host == NULL) { 1000 if (ci == NULL) {
873 result = 0; 1001 result = 0;
874 continue; 1002 continue;
875 } 1003 }
1004 if (ci->host == NULL)
1005 match_test_missing_fatal("Host", "host");
876 if (match_hostname(ci->host, arg) != 1) 1006 if (match_hostname(ci->host, arg) != 1)
877 result = 0; 1007 result = 0;
878 else 1008 else
879 debug("connection from %.100s matched 'Host " 1009 debug("connection from %.100s matched 'Host "
880 "%.100s' at line %d", ci->host, arg, line); 1010 "%.100s' at line %d", ci->host, arg, line);
881 } else if (strcasecmp(attrib, "address") == 0) { 1011 } else if (strcasecmp(attrib, "address") == 0) {
882 if (ci == NULL || ci->address == NULL) { 1012 if (ci == NULL) {
883 result = 0; 1013 result = 0;
884 continue; 1014 continue;
885 } 1015 }
1016 if (ci->address == NULL)
1017 match_test_missing_fatal("Address", "addr");
886 switch (addr_match_list(ci->address, arg)) { 1018 switch (addr_match_list(ci->address, arg)) {
887 case 1: 1019 case 1:
888 debug("connection from %.100s matched 'Address " 1020 debug("connection from %.100s matched 'Address "
@@ -896,10 +1028,13 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
896 return -1; 1028 return -1;
897 } 1029 }
898 } else if (strcasecmp(attrib, "localaddress") == 0){ 1030 } else if (strcasecmp(attrib, "localaddress") == 0){
899 if (ci == NULL || ci->laddress == NULL) { 1031 if (ci == NULL) {
900 result = 0; 1032 result = 0;
901 continue; 1033 continue;
902 } 1034 }
1035 if (ci->laddress == NULL)
1036 match_test_missing_fatal("LocalAddress",
1037 "laddr");
903 switch (addr_match_list(ci->laddress, arg)) { 1038 switch (addr_match_list(ci->laddress, arg)) {
904 case 1: 1039 case 1:
905 debug("connection from %.100s matched " 1040 debug("connection from %.100s matched "
@@ -919,10 +1054,12 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
919 arg); 1054 arg);
920 return -1; 1055 return -1;
921 } 1056 }
922 if (ci == NULL || ci->lport == 0) { 1057 if (ci == NULL) {
923 result = 0; 1058 result = 0;
924 continue; 1059 continue;
925 } 1060 }
1061 if (ci->lport == 0)
1062 match_test_missing_fatal("LocalPort", "lport");
926 /* TODO support port lists */ 1063 /* TODO support port lists */
927 if (port == ci->lport) 1064 if (port == ci->lport)
928 debug("connection from %.100s matched " 1065 debug("connection from %.100s matched "
@@ -930,6 +1067,16 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
930 ci->laddress, port, line); 1067 ci->laddress, port, line);
931 else 1068 else
932 result = 0; 1069 result = 0;
1070 } else if (strcasecmp(attrib, "rdomain") == 0) {
1071 if (ci == NULL || ci->rdomain == NULL) {
1072 result = 0;
1073 continue;
1074 }
1075 if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1076 result = 0;
1077 else
1078 debug("user %.100s matched 'RDomain %.100s' at "
1079 "line %d", ci->rdomain, arg, line);
933 } else { 1080 } else {
934 error("Unsupported Match attribute %s", attrib); 1081 error("Unsupported Match attribute %s", attrib);
935 return -1; 1082 return -1;
@@ -952,6 +1099,11 @@ struct multistate {
952 char *key; 1099 char *key;
953 int value; 1100 int value;
954}; 1101};
1102static const struct multistate multistate_flag[] = {
1103 { "yes", 1 },
1104 { "no", 0 },
1105 { NULL, -1 }
1106};
955static const struct multistate multistate_addressfamily[] = { 1107static const struct multistate multistate_addressfamily[] = {
956 { "inet", AF_INET }, 1108 { "inet", AF_INET },
957 { "inet6", AF_INET6 }, 1109 { "inet6", AF_INET6 },
@@ -1001,6 +1153,7 @@ process_server_config_line(ServerOptions *options, char *line,
1001 size_t len; 1153 size_t len;
1002 long long val64; 1154 long long val64;
1003 const struct multistate *multistate_ptr; 1155 const struct multistate *multistate_ptr;
1156 const char *errstr;
1004 1157
1005 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ 1158 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1006 if ((len = strlen(line)) == 0) 1159 if ((len = strlen(line)) == 0)
@@ -1088,20 +1241,33 @@ process_server_config_line(ServerOptions *options, char *line,
1088 /* check for bare IPv6 address: no "[]" and 2 or more ":" */ 1241 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
1089 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL 1242 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1090 && strchr(p+1, ':') != NULL) { 1243 && strchr(p+1, ':') != NULL) {
1091 queue_listen_addr(options, arg, 0);
1092 break;
1093 }
1094 p = hpdelim(&arg);
1095 if (p == NULL)
1096 fatal("%s line %d: bad address:port usage",
1097 filename, linenum);
1098 p = cleanhostname(p);
1099 if (arg == NULL)
1100 port = 0; 1244 port = 0;
1101 else if ((port = a2port(arg)) <= 0) 1245 p = arg;
1102 fatal("%s line %d: bad port number", filename, linenum); 1246 } else {
1247 p = hpdelim(&arg);
1248 if (p == NULL)
1249 fatal("%s line %d: bad address:port usage",
1250 filename, linenum);
1251 p = cleanhostname(p);
1252 if (arg == NULL)
1253 port = 0;
1254 else if ((port = a2port(arg)) <= 0)
1255 fatal("%s line %d: bad port number",
1256 filename, linenum);
1257 }
1258 /* Optional routing table */
1259 arg2 = NULL;
1260 if ((arg = strdelim(&cp)) != NULL) {
1261 if (strcmp(arg, "rdomain") != 0 ||
1262 (arg2 = strdelim(&cp)) == NULL)
1263 fatal("%s line %d: bad ListenAddress syntax",
1264 filename, linenum);
1265 if (!valid_rdomain(arg2))
1266 fatal("%s line %d: bad routing domain",
1267 filename, linenum);
1268 }
1103 1269
1104 queue_listen_addr(options, p, port); 1270 queue_listen_addr(options, p, arg2, port);
1105 1271
1106 break; 1272 break;
1107 1273
@@ -1128,22 +1294,12 @@ process_server_config_line(ServerOptions *options, char *line,
1128 break; 1294 break;
1129 1295
1130 case sHostKeyFile: 1296 case sHostKeyFile:
1131 intptr = &options->num_host_key_files;
1132 if (*intptr >= MAX_HOSTKEYS)
1133 fatal("%s line %d: too many host keys specified (max %d).",
1134 filename, linenum, MAX_HOSTKEYS);
1135 charptr = &options->host_key_files[*intptr];
1136 parse_filename:
1137 arg = strdelim(&cp); 1297 arg = strdelim(&cp);
1138 if (!arg || *arg == '\0') 1298 if (!arg || *arg == '\0')
1139 fatal("%s line %d: missing file name.", 1299 fatal("%s line %d: missing file name.",
1140 filename, linenum); 1300 filename, linenum);
1141 if (*activep && *charptr == NULL) { 1301 if (*activep)
1142 *charptr = derelativise_path(arg); 1302 servconf_add_hostkey(filename, linenum, options, arg);
1143 /* increase optional counter */
1144 if (intptr != NULL)
1145 *intptr = *intptr + 1;
1146 }
1147 break; 1303 break;
1148 1304
1149 case sHostKeyAgent: 1305 case sHostKeyAgent:
@@ -1158,17 +1314,28 @@ process_server_config_line(ServerOptions *options, char *line,
1158 break; 1314 break;
1159 1315
1160 case sHostCertificate: 1316 case sHostCertificate:
1161 intptr = &options->num_host_cert_files; 1317 arg = strdelim(&cp);
1162 if (*intptr >= MAX_HOSTKEYS) 1318 if (!arg || *arg == '\0')
1163 fatal("%s line %d: too many host certificates " 1319 fatal("%s line %d: missing file name.",
1164 "specified (max %d).", filename, linenum, 1320 filename, linenum);
1165 MAX_HOSTCERTS); 1321 if (*activep)
1166 charptr = &options->host_cert_files[*intptr]; 1322 servconf_add_hostcert(filename, linenum, options, arg);
1167 goto parse_filename; 1323 break;
1168 1324
1169 case sPidFile: 1325 case sPidFile:
1170 charptr = &options->pid_file; 1326 charptr = &options->pid_file;
1171 goto parse_filename; 1327 parse_filename:
1328 arg = strdelim(&cp);
1329 if (!arg || *arg == '\0')
1330 fatal("%s line %d: missing file name.",
1331 filename, linenum);
1332 if (*activep && *charptr == NULL) {
1333 *charptr = derelativise_path(arg);
1334 /* increase optional counter */
1335 if (intptr != NULL)
1336 *intptr = *intptr + 1;
1337 }
1338 break;
1172 1339
1173 case sPermitRootLogin: 1340 case sPermitRootLogin:
1174 intptr = &options->permit_root_login; 1341 intptr = &options->permit_root_login;
@@ -1178,21 +1345,8 @@ process_server_config_line(ServerOptions *options, char *line,
1178 case sIgnoreRhosts: 1345 case sIgnoreRhosts:
1179 intptr = &options->ignore_rhosts; 1346 intptr = &options->ignore_rhosts;
1180 parse_flag: 1347 parse_flag:
1181 arg = strdelim(&cp); 1348 multistate_ptr = multistate_flag;
1182 if (!arg || *arg == '\0') 1349 goto parse_multistate;
1183 fatal("%s line %d: missing yes/no argument.",
1184 filename, linenum);
1185 value = 0; /* silence compiler */
1186 if (strcmp(arg, "yes") == 0)
1187 value = 1;
1188 else if (strcmp(arg, "no") == 0)
1189 value = 0;
1190 else
1191 fatal("%s line %d: Bad yes/no argument: %s",
1192 filename, linenum, arg);
1193 if (*activep && *intptr == -1)
1194 *intptr = value;
1195 break;
1196 1350
1197 case sIgnoreUserKnownHosts: 1351 case sIgnoreUserKnownHosts:
1198 intptr = &options->ignore_user_known_hosts; 1352 intptr = &options->ignore_user_known_hosts;
@@ -1289,10 +1443,9 @@ process_server_config_line(ServerOptions *options, char *line,
1289 intptr = &options->x11_display_offset; 1443 intptr = &options->x11_display_offset;
1290 parse_int: 1444 parse_int:
1291 arg = strdelim(&cp); 1445 arg = strdelim(&cp);
1292 if (!arg || *arg == '\0') 1446 if ((errstr = atoi_err(arg, &value)) != NULL)
1293 fatal("%s line %d: missing integer value.", 1447 fatal("%s line %d: integer value %s.",
1294 filename, linenum); 1448 filename, linenum, errstr);
1295 value = atoi(arg);
1296 if (*activep && *intptr == -1) 1449 if (*activep && *intptr == -1)
1297 *intptr = value; 1450 *intptr = value;
1298 break; 1451 break;
@@ -1412,55 +1565,47 @@ process_server_config_line(ServerOptions *options, char *line,
1412 1565
1413 case sAllowUsers: 1566 case sAllowUsers:
1414 while ((arg = strdelim(&cp)) && *arg != '\0') { 1567 while ((arg = strdelim(&cp)) && *arg != '\0') {
1415 if (options->num_allow_users >= MAX_ALLOW_USERS)
1416 fatal("%s line %d: too many allow users.",
1417 filename, linenum);
1418 if (match_user(NULL, NULL, NULL, arg) == -1) 1568 if (match_user(NULL, NULL, NULL, arg) == -1)
1419 fatal("%s line %d: invalid AllowUsers pattern: " 1569 fatal("%s line %d: invalid AllowUsers pattern: "
1420 "\"%.100s\"", filename, linenum, arg); 1570 "\"%.100s\"", filename, linenum, arg);
1421 if (!*activep) 1571 if (!*activep)
1422 continue; 1572 continue;
1423 options->allow_users[options->num_allow_users++] = 1573 array_append(filename, linenum, "AllowUsers",
1424 xstrdup(arg); 1574 &options->allow_users, &options->num_allow_users,
1575 arg);
1425 } 1576 }
1426 break; 1577 break;
1427 1578
1428 case sDenyUsers: 1579 case sDenyUsers:
1429 while ((arg = strdelim(&cp)) && *arg != '\0') { 1580 while ((arg = strdelim(&cp)) && *arg != '\0') {
1430 if (options->num_deny_users >= MAX_DENY_USERS)
1431 fatal("%s line %d: too many deny users.",
1432 filename, linenum);
1433 if (match_user(NULL, NULL, NULL, arg) == -1) 1581 if (match_user(NULL, NULL, NULL, arg) == -1)
1434 fatal("%s line %d: invalid DenyUsers pattern: " 1582 fatal("%s line %d: invalid DenyUsers pattern: "
1435 "\"%.100s\"", filename, linenum, arg); 1583 "\"%.100s\"", filename, linenum, arg);
1436 if (!*activep) 1584 if (!*activep)
1437 continue; 1585 continue;
1438 options->deny_users[options->num_deny_users++] = 1586 array_append(filename, linenum, "DenyUsers",
1439 xstrdup(arg); 1587 &options->deny_users, &options->num_deny_users,
1588 arg);
1440 } 1589 }
1441 break; 1590 break;
1442 1591
1443 case sAllowGroups: 1592 case sAllowGroups:
1444 while ((arg = strdelim(&cp)) && *arg != '\0') { 1593 while ((arg = strdelim(&cp)) && *arg != '\0') {
1445 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1446 fatal("%s line %d: too many allow groups.",
1447 filename, linenum);
1448 if (!*activep) 1594 if (!*activep)
1449 continue; 1595 continue;
1450 options->allow_groups[options->num_allow_groups++] = 1596 array_append(filename, linenum, "AllowGroups",
1451 xstrdup(arg); 1597 &options->allow_groups, &options->num_allow_groups,
1598 arg);
1452 } 1599 }
1453 break; 1600 break;
1454 1601
1455 case sDenyGroups: 1602 case sDenyGroups:
1456 while ((arg = strdelim(&cp)) && *arg != '\0') { 1603 while ((arg = strdelim(&cp)) && *arg != '\0') {
1457 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1458 fatal("%s line %d: too many deny groups.",
1459 filename, linenum);
1460 if (!*activep) 1604 if (!*activep)
1461 continue; 1605 continue;
1462 options->deny_groups[options->num_deny_groups++] = 1606 array_append(filename, linenum, "DenyGroups",
1463 xstrdup(arg); 1607 &options->deny_groups, &options->num_deny_groups,
1608 arg);
1464 } 1609 }
1465 break; 1610 break;
1466 1611
@@ -1579,14 +1724,12 @@ process_server_config_line(ServerOptions *options, char *line,
1579 case sAuthorizedKeysFile: 1724 case sAuthorizedKeysFile:
1580 if (*activep && options->num_authkeys_files == 0) { 1725 if (*activep && options->num_authkeys_files == 0) {
1581 while ((arg = strdelim(&cp)) && *arg != '\0') { 1726 while ((arg = strdelim(&cp)) && *arg != '\0') {
1582 if (options->num_authkeys_files >= 1727 arg = tilde_expand_filename(arg, getuid());
1583 MAX_AUTHKEYS_FILES) 1728 array_append(filename, linenum,
1584 fatal("%s line %d: " 1729 "AuthorizedKeysFile",
1585 "too many authorized keys files.", 1730 &options->authorized_keys_files,
1586 filename, linenum); 1731 &options->num_authkeys_files, arg);
1587 options->authorized_keys_files[ 1732 free(arg);
1588 options->num_authkeys_files++] =
1589 tilde_expand_filename(arg, getuid());
1590 } 1733 }
1591 } 1734 }
1592 return 0; 1735 return 0;
@@ -1618,13 +1761,11 @@ process_server_config_line(ServerOptions *options, char *line,
1618 if (strchr(arg, '=') != NULL) 1761 if (strchr(arg, '=') != NULL)
1619 fatal("%s line %d: Invalid environment name.", 1762 fatal("%s line %d: Invalid environment name.",
1620 filename, linenum); 1763 filename, linenum);
1621 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1622 fatal("%s line %d: too many allow env.",
1623 filename, linenum);
1624 if (!*activep) 1764 if (!*activep)
1625 continue; 1765 continue;
1626 options->accept_env[options->num_accept_env++] = 1766 array_append(filename, linenum, "AcceptEnv",
1627 xstrdup(arg); 1767 &options->accept_env, &options->num_accept_env,
1768 arg);
1628 } 1769 }
1629 break; 1770 break;
1630 1771
@@ -1663,9 +1804,9 @@ process_server_config_line(ServerOptions *options, char *line,
1663 if (!arg || *arg == '\0') 1804 if (!arg || *arg == '\0')
1664 fatal("%s line %d: missing PermitOpen specification", 1805 fatal("%s line %d: missing PermitOpen specification",
1665 filename, linenum); 1806 filename, linenum);
1666 i = options->num_permitted_opens; /* modified later */ 1807 value = options->num_permitted_opens; /* modified later */
1667 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { 1808 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
1668 if (*activep && i == 0) { 1809 if (*activep && value == 0) {
1669 options->num_permitted_opens = 1; 1810 options->num_permitted_opens = 1;
1670 options->permitted_opens = xcalloc(1, 1811 options->permitted_opens = xcalloc(1,
1671 sizeof(*options->permitted_opens)); 1812 sizeof(*options->permitted_opens));
@@ -1683,16 +1824,13 @@ process_server_config_line(ServerOptions *options, char *line,
1683 if (arg == NULL || ((port = permitopen_port(arg)) < 0)) 1824 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
1684 fatal("%s line %d: bad port number in " 1825 fatal("%s line %d: bad port number in "
1685 "PermitOpen", filename, linenum); 1826 "PermitOpen", filename, linenum);
1686 if (*activep && i == 0) { 1827 if (*activep && value == 0) {
1687 options->permitted_opens = xrecallocarray( 1828 array_append(filename, linenum,
1688 options->permitted_opens, 1829 "PermitOpen",
1689 options->num_permitted_opens, 1830 &options->permitted_opens,
1690 options->num_permitted_opens + 1, 1831 &options->num_permitted_opens, arg2);
1691 sizeof(*options->permitted_opens)); 1832 }
1692 i = options->num_permitted_opens++; 1833 free(arg2);
1693 options->permitted_opens[i] = arg2;
1694 } else
1695 free(arg2);
1696 } 1834 }
1697 break; 1835 break;
1698 1836
@@ -1815,11 +1953,6 @@ process_server_config_line(ServerOptions *options, char *line,
1815 value = 0; /* seen "any" pseudo-method */ 1953 value = 0; /* seen "any" pseudo-method */
1816 value2 = 0; /* sucessfully parsed any method */ 1954 value2 = 0; /* sucessfully parsed any method */
1817 while ((arg = strdelim(&cp)) && *arg != '\0') { 1955 while ((arg = strdelim(&cp)) && *arg != '\0') {
1818 if (options->num_auth_methods >=
1819 MAX_AUTH_METHODS)
1820 fatal("%s line %d: "
1821 "too many authentication methods.",
1822 filename, linenum);
1823 if (strcmp(arg, "any") == 0) { 1956 if (strcmp(arg, "any") == 0) {
1824 if (options->num_auth_methods > 0) { 1957 if (options->num_auth_methods > 0) {
1825 fatal("%s line %d: \"any\" " 1958 fatal("%s line %d: \"any\" "
@@ -1840,8 +1973,10 @@ process_server_config_line(ServerOptions *options, char *line,
1840 value2 = 1; 1973 value2 = 1;
1841 if (!*activep) 1974 if (!*activep)
1842 continue; 1975 continue;
1843 options->auth_methods[ 1976 array_append(filename, linenum,
1844 options->num_auth_methods++] = xstrdup(arg); 1977 "AuthenticationMethods",
1978 &options->auth_methods,
1979 &options->num_auth_methods, arg);
1845 } 1980 }
1846 if (value2 == 0) { 1981 if (value2 == 0) {
1847 fatal("%s line %d: no AuthenticationMethods " 1982 fatal("%s line %d: no AuthenticationMethods "
@@ -1883,6 +2018,20 @@ process_server_config_line(ServerOptions *options, char *line,
1883 intptr = &options->expose_userauth_info; 2018 intptr = &options->expose_userauth_info;
1884 goto parse_flag; 2019 goto parse_flag;
1885 2020
2021 case sRDomain:
2022 charptr = &options->routing_domain;
2023 arg = strdelim(&cp);
2024 if (!arg || *arg == '\0')
2025 fatal("%.200s line %d: Missing argument.",
2026 filename, linenum);
2027 if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2028 !valid_rdomain(arg))
2029 fatal("%s line %d: bad routing domain",
2030 filename, linenum);
2031 if (*activep && *charptr == NULL)
2032 *charptr = xstrdup(arg);
2033 break;
2034
1886 case sDeprecated: 2035 case sDeprecated:
1887 case sIgnore: 2036 case sIgnore:
1888 case sUnsupported: 2037 case sUnsupported:
@@ -1963,6 +2112,8 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec)
1963 ci->user = xstrdup(p + 5); 2112 ci->user = xstrdup(p + 5);
1964 } else if (strncmp(p, "laddr=", 6) == 0) { 2113 } else if (strncmp(p, "laddr=", 6) == 0) {
1965 ci->laddress = xstrdup(p + 6); 2114 ci->laddress = xstrdup(p + 6);
2115 } else if (strncmp(p, "rdomain=", 8) == 0) {
2116 ci->rdomain = xstrdup(p + 8);
1966 } else if (strncmp(p, "lport=", 6) == 0) { 2117 } else if (strncmp(p, "lport=", 6) == 0) {
1967 ci->lport = a2port(p + 6); 2118 ci->lport = a2port(p + 6);
1968 if (ci->lport == -1) { 2119 if (ci->lport == -1) {
@@ -1980,19 +2131,6 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec)
1980} 2131}
1981 2132
1982/* 2133/*
1983 * returns 1 for a complete spec, 0 for partial spec and -1 for an
1984 * empty spec.
1985 */
1986int server_match_spec_complete(struct connection_info *ci)
1987{
1988 if (ci->user && ci->host && ci->address)
1989 return 1; /* complete */
1990 if (!ci->user && !ci->host && !ci->address)
1991 return -1; /* empty */
1992 return 0; /* partial */
1993}
1994
1995/*
1996 * Copy any supported values that are set. 2134 * Copy any supported values that are set.
1997 * 2135 *
1998 * If the preauth flag is set, we do not bother copying the string or 2136 * If the preauth flag is set, we do not bother copying the string or
@@ -2057,17 +2195,16 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2057 dst->n = src->n; \ 2195 dst->n = src->n; \
2058 } \ 2196 } \
2059} while(0) 2197} while(0)
2060#define M_CP_STRARRAYOPT(n, num_n) do {\ 2198#define M_CP_STRARRAYOPT(s, num_s) do {\
2061 if (src->num_n != 0) { \ 2199 u_int i; \
2062 for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ 2200 if (src->num_s != 0) { \
2063 dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ 2201 for (i = 0; i < dst->num_s; i++) \
2064 } \ 2202 free(dst->s[i]); \
2065} while(0) 2203 free(dst->s); \
2066#define M_CP_STRARRAYOPT_ALLOC(n, num_n) do { \ 2204 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2067 if (src->num_n != 0) { \ 2205 for (i = 0; i < src->num_s; i++) \
2068 dst->n = xcalloc(src->num_n, sizeof(*dst->n)); \ 2206 dst->s[i] = xstrdup(src->s[i]); \
2069 M_CP_STRARRAYOPT(n, num_n); \ 2207 dst->num_s = src->num_s; \
2070 dst->num_n = src->num_n; \
2071 } \ 2208 } \
2072} while(0) 2209} while(0)
2073 2210
@@ -2100,7 +2237,6 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2100#undef M_CP_INTOPT 2237#undef M_CP_INTOPT
2101#undef M_CP_STROPT 2238#undef M_CP_STROPT
2102#undef M_CP_STRARRAYOPT 2239#undef M_CP_STRARRAYOPT
2103#undef M_CP_STRARRAYOPT_ALLOC
2104 2240
2105void 2241void
2106parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, 2242parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
@@ -2231,45 +2367,61 @@ dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2231 printf("\n"); 2367 printf("\n");
2232} 2368}
2233 2369
2234void 2370static char *
2235dump_config(ServerOptions *o) 2371format_listen_addrs(struct listenaddr *la)
2236{ 2372{
2237 u_int i; 2373 int r;
2238 int ret;
2239 struct addrinfo *ai; 2374 struct addrinfo *ai;
2240 char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; 2375 char addr[NI_MAXHOST], port[NI_MAXSERV];
2241 char *laddr1 = xstrdup(""), *laddr2 = NULL; 2376 char *laddr1 = xstrdup(""), *laddr2 = NULL;
2242 2377
2243 /* these are usually at the top of the config */
2244 for (i = 0; i < o->num_ports; i++)
2245 printf("port %d\n", o->ports[i]);
2246 dump_cfg_fmtint(sAddressFamily, o->address_family);
2247
2248 /* 2378 /*
2249 * ListenAddress must be after Port. add_one_listen_addr pushes 2379 * ListenAddress must be after Port. add_one_listen_addr pushes
2250 * addresses onto a stack, so to maintain ordering we need to 2380 * addresses onto a stack, so to maintain ordering we need to
2251 * print these in reverse order. 2381 * print these in reverse order.
2252 */ 2382 */
2253 for (ai = o->listen_addrs; ai; ai = ai->ai_next) { 2383 for (ai = la->addrs; ai; ai = ai->ai_next) {
2254 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, 2384 if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2255 sizeof(addr), port, sizeof(port), 2385 sizeof(addr), port, sizeof(port),
2256 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 2386 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2257 error("getnameinfo failed: %.100s", 2387 error("getnameinfo: %.100s", ssh_gai_strerror(r));
2258 (ret != EAI_SYSTEM) ? gai_strerror(ret) : 2388 continue;
2259 strerror(errno)); 2389 }
2390 laddr2 = laddr1;
2391 if (ai->ai_family == AF_INET6) {
2392 xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2393 addr, port,
2394 la->rdomain == NULL ? "" : " rdomain ",
2395 la->rdomain == NULL ? "" : la->rdomain,
2396 laddr2);
2260 } else { 2397 } else {
2261 laddr2 = laddr1; 2398 xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2262 if (ai->ai_family == AF_INET6) 2399 addr, port,
2263 xasprintf(&laddr1, "listenaddress [%s]:%s\n%s", 2400 la->rdomain == NULL ? "" : " rdomain ",
2264 addr, port, laddr2); 2401 la->rdomain == NULL ? "" : la->rdomain,
2265 else 2402 laddr2);
2266 xasprintf(&laddr1, "listenaddress %s:%s\n%s",
2267 addr, port, laddr2);
2268 free(laddr2);
2269 } 2403 }
2404 free(laddr2);
2405 }
2406 return laddr1;
2407}
2408
2409void
2410dump_config(ServerOptions *o)
2411{
2412 char *s;
2413 u_int i;
2414
2415 /* these are usually at the top of the config */
2416 for (i = 0; i < o->num_ports; i++)
2417 printf("port %d\n", o->ports[i]);
2418 dump_cfg_fmtint(sAddressFamily, o->address_family);
2419
2420 for (i = 0; i < o->num_listen_addrs; i++) {
2421 s = format_listen_addrs(&o->listen_addrs[i]);
2422 printf("%s", s);
2423 free(s);
2270 } 2424 }
2271 printf("%s", laddr1);
2272 free(laddr1);
2273 2425
2274 /* integer arguments */ 2426 /* integer arguments */
2275#ifdef USE_PAM 2427#ifdef USE_PAM
@@ -2358,6 +2510,7 @@ dump_config(ServerOptions *o)
2358 o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); 2510 o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2359 dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? 2511 dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
2360 o->pubkey_key_types : KEX_DEFAULT_PK_ALG); 2512 o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2513 dump_cfg_string(sRDomain, o->routing_domain);
2361 2514
2362 /* string arguments requiring a lookup */ 2515 /* string arguments requiring a lookup */
2363 dump_cfg_string(sLogLevel, log_level_name(o->log_level)); 2516 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
@@ -2386,11 +2539,13 @@ dump_config(ServerOptions *o)
2386 printf("maxstartups %d:%d:%d\n", o->max_startups_begin, 2539 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
2387 o->max_startups_rate, o->max_startups); 2540 o->max_startups_rate, o->max_startups);
2388 2541
2389 for (i = 0; tunmode_desc[i].val != -1; i++) 2542 s = NULL;
2543 for (i = 0; tunmode_desc[i].val != -1; i++) {
2390 if (tunmode_desc[i].val == o->permit_tun) { 2544 if (tunmode_desc[i].val == o->permit_tun) {
2391 s = tunmode_desc[i].text; 2545 s = tunmode_desc[i].text;
2392 break; 2546 break;
2393 } 2547 }
2548 }
2394 dump_cfg_string(sPermitTunnel, s); 2549 dump_cfg_string(sPermitTunnel, s);
2395 2550
2396 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2551 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));