summaryrefslogtreecommitdiff
path: root/servconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'servconf.c')
-rw-r--r--servconf.c561
1 files changed, 359 insertions, 202 deletions
diff --git a/servconf.c b/servconf.c
index 9daa182c0..0a8f6fd62 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.313 2017/10/04 18:49:30 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;
@@ -191,10 +201,45 @@ assemble_algorithms(ServerOptions *o)
191 fatal("kex_assemble_names failed"); 201 fatal("kex_assemble_names failed");
192} 202}
193 203
204static void
205array_append(const char *file, const int line, const char *directive,
206 char ***array, u_int *lp, const char *s)
207{
208
209 if (*lp >= INT_MAX)
210 fatal("%s line %d: Too many %s entries", file, line, directive);
211
212 *array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
213 (*array)[*lp] = xstrdup(s);
214 (*lp)++;
215}
216
217void
218servconf_add_hostkey(const char *file, const int line,
219 ServerOptions *options, const char *path)
220{
221 char *apath = derelativise_path(path);
222
223 array_append(file, line, "HostKey",
224 &options->host_key_files, &options->num_host_key_files, apath);
225 free(apath);
226}
227
228void
229servconf_add_hostcert(const char *file, const int line,
230 ServerOptions *options, const char *path)
231{
232 char *apath = derelativise_path(path);
233
234 array_append(file, line, "HostCertificate",
235 &options->host_cert_files, &options->num_host_cert_files, apath);
236 free(apath);
237}
238
194void 239void
195fill_default_server_options(ServerOptions *options) 240fill_default_server_options(ServerOptions *options)
196{ 241{
197 int i; 242 u_int i;
198 243
199 /* Portable-specific options */ 244 /* Portable-specific options */
200 if (options->use_pam == -1) 245 if (options->use_pam == -1)
@@ -203,14 +248,18 @@ fill_default_server_options(ServerOptions *options)
203 /* Standard Options */ 248 /* Standard Options */
204 if (options->num_host_key_files == 0) { 249 if (options->num_host_key_files == 0) {
205 /* fill default hostkeys for protocols */ 250 /* fill default hostkeys for protocols */
206 options->host_key_files[options->num_host_key_files++] = 251 servconf_add_hostkey("[default]", 0, options,
207 _PATH_HOST_RSA_KEY_FILE; 252 _PATH_HOST_RSA_KEY_FILE);
208#ifdef OPENSSL_HAS_ECC 253#ifdef OPENSSL_HAS_ECC
209 options->host_key_files[options->num_host_key_files++] = 254 servconf_add_hostkey("[default]", 0, options,
210 _PATH_HOST_ECDSA_KEY_FILE; 255 _PATH_HOST_ECDSA_KEY_FILE);
211#endif 256#endif
212 options->host_key_files[options->num_host_key_files++] = 257 servconf_add_hostkey("[default]", 0, options,
213 _PATH_HOST_ED25519_KEY_FILE; 258 _PATH_HOST_ED25519_KEY_FILE);
259#ifdef WITH_XMSS
260 servconf_add_hostkey("[default]", 0, options,
261 _PATH_HOST_XMSS_KEY_FILE);
262#endif /* WITH_XMSS */
214 } 263 }
215 /* No certificates by default */ 264 /* No certificates by default */
216 if (options->num_ports == 0) 265 if (options->num_ports == 0)
@@ -218,7 +267,7 @@ fill_default_server_options(ServerOptions *options)
218 if (options->address_family == -1) 267 if (options->address_family == -1)
219 options->address_family = AF_UNSPEC; 268 options->address_family = AF_UNSPEC;
220 if (options->listen_addrs == NULL) 269 if (options->listen_addrs == NULL)
221 add_listen_addr(options, NULL, 0); 270 add_listen_addr(options, NULL, NULL, 0);
222 if (options->pid_file == NULL) 271 if (options->pid_file == NULL)
223 options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE); 272 options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
224 if (options->login_grace_time == -1) 273 if (options->login_grace_time == -1)
@@ -318,10 +367,14 @@ fill_default_server_options(ServerOptions *options)
318 if (options->client_alive_count_max == -1) 367 if (options->client_alive_count_max == -1)
319 options->client_alive_count_max = 3; 368 options->client_alive_count_max = 3;
320 if (options->num_authkeys_files == 0) { 369 if (options->num_authkeys_files == 0) {
321 options->authorized_keys_files[options->num_authkeys_files++] = 370 array_append("[default]", 0, "AuthorizedKeysFiles",
322 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); 371 &options->authorized_keys_files,
323 options->authorized_keys_files[options->num_authkeys_files++] = 372 &options->num_authkeys_files,
324 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); 373 _PATH_SSH_USER_PERMITTED_KEYS);
374 array_append("[default]", 0, "AuthorizedKeysFiles",
375 &options->authorized_keys_files,
376 &options->num_authkeys_files,
377 _PATH_SSH_USER_PERMITTED_KEYS2);
325 } 378 }
326 if (options->permit_tun == -1) 379 if (options->permit_tun == -1)
327 options->permit_tun = SSH_TUNMODE_NO; 380 options->permit_tun = SSH_TUNMODE_NO;
@@ -365,6 +418,7 @@ fill_default_server_options(ServerOptions *options)
365 CLEAR_ON_NONE(options->authorized_principals_file); 418 CLEAR_ON_NONE(options->authorized_principals_file);
366 CLEAR_ON_NONE(options->adm_forced_command); 419 CLEAR_ON_NONE(options->adm_forced_command);
367 CLEAR_ON_NONE(options->chroot_directory); 420 CLEAR_ON_NONE(options->chroot_directory);
421 CLEAR_ON_NONE(options->routing_domain);
368 for (i = 0; i < options->num_host_key_files; i++) 422 for (i = 0; i < options->num_host_key_files; i++)
369 CLEAR_ON_NONE(options->host_key_files[i]); 423 CLEAR_ON_NONE(options->host_key_files[i]);
370 for (i = 0; i < options->num_host_cert_files; i++) 424 for (i = 0; i < options->num_host_cert_files; i++)
@@ -400,8 +454,7 @@ typedef enum {
400 sPermitRootLogin, sLogFacility, sLogLevel, 454 sPermitRootLogin, sLogFacility, sLogLevel,
401 sRhostsRSAAuthentication, sRSAAuthentication, 455 sRhostsRSAAuthentication, sRSAAuthentication,
402 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 456 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
403 sKerberosGetAFSToken, 457 sKerberosGetAFSToken, sChallengeResponseAuthentication,
404 sKerberosTgtPassing, sChallengeResponseAuthentication,
405 sPasswordAuthentication, sKbdInteractiveAuthentication, 458 sPasswordAuthentication, sKbdInteractiveAuthentication,
406 sListenAddress, sAddressFamily, 459 sListenAddress, sAddressFamily,
407 sPrintMotd, sPrintLastLog, sIgnoreRhosts, 460 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
@@ -429,7 +482,7 @@ typedef enum {
429 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, 482 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
430 sStreamLocalBindMask, sStreamLocalBindUnlink, 483 sStreamLocalBindMask, sStreamLocalBindUnlink,
431 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, 484 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
432 sExposeAuthInfo, 485 sExposeAuthInfo, sRDomain,
433 sDebianBanner, 486 sDebianBanner,
434 sDeprecated, sIgnore, sUnsupported 487 sDeprecated, sIgnore, sUnsupported
435} ServerOpCodes; 488} ServerOpCodes;
@@ -584,6 +637,7 @@ static struct {
584 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, 637 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
585 { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, 638 { "disableforwarding", sDisableForwarding, SSHCFG_ALL },
586 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, 639 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
640 { "rdomain", sRDomain, SSHCFG_ALL },
587 { "debianbanner", sDebianBanner, SSHCFG_GLOBAL }, 641 { "debianbanner", sDebianBanner, SSHCFG_GLOBAL },
588 { NULL, sBadOption, 0 } 642 { NULL, sBadOption, 0 }
589}; 643};
@@ -638,23 +692,51 @@ derelativise_path(const char *path)
638} 692}
639 693
640static void 694static void
641add_listen_addr(ServerOptions *options, char *addr, int port) 695add_listen_addr(ServerOptions *options, const char *addr,
696 const char *rdomain, int port)
642{ 697{
643 u_int i; 698 u_int i;
644 699
645 if (port == 0) 700 if (port > 0)
646 for (i = 0; i < options->num_ports; i++) 701 add_one_listen_addr(options, addr, rdomain, port);
647 add_one_listen_addr(options, addr, options->ports[i]); 702 else {
648 else 703 for (i = 0; i < options->num_ports; i++) {
649 add_one_listen_addr(options, addr, port); 704 add_one_listen_addr(options, addr, rdomain,
705 options->ports[i]);
706 }
707 }
650} 708}
651 709
652static void 710static void
653add_one_listen_addr(ServerOptions *options, char *addr, int port) 711add_one_listen_addr(ServerOptions *options, const char *addr,
712 const char *rdomain, int port)
654{ 713{
655 struct addrinfo hints, *ai, *aitop; 714 struct addrinfo hints, *ai, *aitop;
656 char strport[NI_MAXSERV]; 715 char strport[NI_MAXSERV];
657 int gaierr; 716 int gaierr;
717 u_int i;
718
719 /* Find listen_addrs entry for this rdomain */
720 for (i = 0; i < options->num_listen_addrs; i++) {
721 if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
722 break;
723 if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
724 continue;
725 if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
726 break;
727 }
728 if (i >= options->num_listen_addrs) {
729 /* No entry for this rdomain; allocate one */
730 if (i >= INT_MAX)
731 fatal("%s: too many listen addresses", __func__);
732 options->listen_addrs = xrecallocarray(options->listen_addrs,
733 options->num_listen_addrs, options->num_listen_addrs + 1,
734 sizeof(*options->listen_addrs));
735 i = options->num_listen_addrs++;
736 if (rdomain != NULL)
737 options->listen_addrs[i].rdomain = xstrdup(rdomain);
738 }
739 /* options->listen_addrs[i] points to the addresses for this rdomain */
658 740
659 memset(&hints, 0, sizeof(hints)); 741 memset(&hints, 0, sizeof(hints));
660 hints.ai_family = options->address_family; 742 hints.ai_family = options->address_family;
@@ -667,8 +749,44 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
667 ssh_gai_strerror(gaierr)); 749 ssh_gai_strerror(gaierr));
668 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 750 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
669 ; 751 ;
670 ai->ai_next = options->listen_addrs; 752 ai->ai_next = options->listen_addrs[i].addrs;
671 options->listen_addrs = aitop; 753 options->listen_addrs[i].addrs = aitop;
754}
755
756/* Returns nonzero if the routing domain name is valid */
757static int
758valid_rdomain(const char *name)
759{
760#if defined(HAVE_SYS_VALID_RDOMAIN)
761 return sys_valid_rdomain(name);
762#elif defined(__OpenBSD__)
763 const char *errstr;
764 long long num;
765 struct rt_tableinfo info;
766 int mib[6];
767 size_t miblen = sizeof(mib);
768
769 if (name == NULL)
770 return 1;
771
772 num = strtonum(name, 0, 255, &errstr);
773 if (errstr != NULL)
774 return 0;
775
776 /* Check whether the table actually exists */
777 memset(mib, 0, sizeof(mib));
778 mib[0] = CTL_NET;
779 mib[1] = PF_ROUTE;
780 mib[4] = NET_RT_TABLE;
781 mib[5] = (int)num;
782 if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
783 return 0;
784
785 return 1;
786#else /* defined(__OpenBSD__) */
787 error("Routing domains are not supported on this platform");
788 return 0;
789#endif
672} 790}
673 791
674/* 792/*
@@ -676,18 +794,19 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
676 * and AddressFamily options. 794 * and AddressFamily options.
677 */ 795 */
678static void 796static void
679queue_listen_addr(ServerOptions *options, char *addr, int port) 797queue_listen_addr(ServerOptions *options, const char *addr,
798 const char *rdomain, int port)
680{ 799{
681 options->queued_listen_addrs = xreallocarray( 800 struct queued_listenaddr *qla;
682 options->queued_listen_addrs, options->num_queued_listens + 1, 801
683 sizeof(addr)); 802 options->queued_listen_addrs = xrecallocarray(
684 options->queued_listen_ports = xreallocarray( 803 options->queued_listen_addrs,
685 options->queued_listen_ports, options->num_queued_listens + 1, 804 options->num_queued_listens, options->num_queued_listens + 1,
686 sizeof(port)); 805 sizeof(*options->queued_listen_addrs));
687 options->queued_listen_addrs[options->num_queued_listens] = 806 qla = &options->queued_listen_addrs[options->num_queued_listens++];
688 xstrdup(addr); 807 qla->addr = xstrdup(addr);
689 options->queued_listen_ports[options->num_queued_listens] = port; 808 qla->port = port;
690 options->num_queued_listens++; 809 qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
691} 810}
692 811
693/* 812/*
@@ -697,6 +816,7 @@ static void
697process_queued_listen_addrs(ServerOptions *options) 816process_queued_listen_addrs(ServerOptions *options)
698{ 817{
699 u_int i; 818 u_int i;
819 struct queued_listenaddr *qla;
700 820
701 if (options->num_ports == 0) 821 if (options->num_ports == 0)
702 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 822 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
@@ -704,15 +824,13 @@ process_queued_listen_addrs(ServerOptions *options)
704 options->address_family = AF_UNSPEC; 824 options->address_family = AF_UNSPEC;
705 825
706 for (i = 0; i < options->num_queued_listens; i++) { 826 for (i = 0; i < options->num_queued_listens; i++) {
707 add_listen_addr(options, options->queued_listen_addrs[i], 827 qla = &options->queued_listen_addrs[i];
708 options->queued_listen_ports[i]); 828 add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
709 free(options->queued_listen_addrs[i]); 829 free(qla->addr);
710 options->queued_listen_addrs[i] = NULL; 830 free(qla->rdomain);
711 } 831 }
712 free(options->queued_listen_addrs); 832 free(options->queued_listen_addrs);
713 options->queued_listen_addrs = NULL; 833 options->queued_listen_addrs = NULL;
714 free(options->queued_listen_ports);
715 options->queued_listen_ports = NULL;
716 options->num_queued_listens = 0; 834 options->num_queued_listens = 0;
717} 835}
718 836
@@ -766,6 +884,7 @@ get_connection_info(int populate, int use_dns)
766 ci.address = ssh_remote_ipaddr(ssh); 884 ci.address = ssh_remote_ipaddr(ssh);
767 ci.laddress = ssh_local_ipaddr(ssh); 885 ci.laddress = ssh_local_ipaddr(ssh);
768 ci.lport = ssh_local_port(ssh); 886 ci.lport = ssh_local_port(ssh);
887 ci.rdomain = ssh_packet_rdomain_in(ssh);
769 return &ci; 888 return &ci;
770} 889}
771 890
@@ -830,6 +949,13 @@ out:
830 return result; 949 return result;
831} 950}
832 951
952static void
953match_test_missing_fatal(const char *criteria, const char *attrib)
954{
955 fatal("'Match %s' in configuration but '%s' not in connection "
956 "test specification.", criteria, attrib);
957}
958
833/* 959/*
834 * All of the attributes on a single Match line are ANDed together, so we need 960 * All of the attributes on a single Match line are ANDed together, so we need
835 * to check every attribute and set the result to zero if any attribute does 961 * to check every attribute and set the result to zero if any attribute does
@@ -867,20 +993,24 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
867 return -1; 993 return -1;
868 } 994 }
869 if (strcasecmp(attrib, "user") == 0) { 995 if (strcasecmp(attrib, "user") == 0) {
870 if (ci == NULL || ci->user == NULL) { 996 if (ci == NULL) {
871 result = 0; 997 result = 0;
872 continue; 998 continue;
873 } 999 }
1000 if (ci->user == NULL)
1001 match_test_missing_fatal("User", "user");
874 if (match_pattern_list(ci->user, arg, 0) != 1) 1002 if (match_pattern_list(ci->user, arg, 0) != 1)
875 result = 0; 1003 result = 0;
876 else 1004 else
877 debug("user %.100s matched 'User %.100s' at " 1005 debug("user %.100s matched 'User %.100s' at "
878 "line %d", ci->user, arg, line); 1006 "line %d", ci->user, arg, line);
879 } else if (strcasecmp(attrib, "group") == 0) { 1007 } else if (strcasecmp(attrib, "group") == 0) {
880 if (ci == NULL || ci->user == NULL) { 1008 if (ci == NULL) {
881 result = 0; 1009 result = 0;
882 continue; 1010 continue;
883 } 1011 }
1012 if (ci->user == NULL)
1013 match_test_missing_fatal("Group", "user");
884 switch (match_cfg_line_group(arg, line, ci->user)) { 1014 switch (match_cfg_line_group(arg, line, ci->user)) {
885 case -1: 1015 case -1:
886 return -1; 1016 return -1;
@@ -888,20 +1018,24 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
888 result = 0; 1018 result = 0;
889 } 1019 }
890 } else if (strcasecmp(attrib, "host") == 0) { 1020 } else if (strcasecmp(attrib, "host") == 0) {
891 if (ci == NULL || ci->host == NULL) { 1021 if (ci == NULL) {
892 result = 0; 1022 result = 0;
893 continue; 1023 continue;
894 } 1024 }
1025 if (ci->host == NULL)
1026 match_test_missing_fatal("Host", "host");
895 if (match_hostname(ci->host, arg) != 1) 1027 if (match_hostname(ci->host, arg) != 1)
896 result = 0; 1028 result = 0;
897 else 1029 else
898 debug("connection from %.100s matched 'Host " 1030 debug("connection from %.100s matched 'Host "
899 "%.100s' at line %d", ci->host, arg, line); 1031 "%.100s' at line %d", ci->host, arg, line);
900 } else if (strcasecmp(attrib, "address") == 0) { 1032 } else if (strcasecmp(attrib, "address") == 0) {
901 if (ci == NULL || ci->address == NULL) { 1033 if (ci == NULL) {
902 result = 0; 1034 result = 0;
903 continue; 1035 continue;
904 } 1036 }
1037 if (ci->address == NULL)
1038 match_test_missing_fatal("Address", "addr");
905 switch (addr_match_list(ci->address, arg)) { 1039 switch (addr_match_list(ci->address, arg)) {
906 case 1: 1040 case 1:
907 debug("connection from %.100s matched 'Address " 1041 debug("connection from %.100s matched 'Address "
@@ -915,10 +1049,13 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
915 return -1; 1049 return -1;
916 } 1050 }
917 } else if (strcasecmp(attrib, "localaddress") == 0){ 1051 } else if (strcasecmp(attrib, "localaddress") == 0){
918 if (ci == NULL || ci->laddress == NULL) { 1052 if (ci == NULL) {
919 result = 0; 1053 result = 0;
920 continue; 1054 continue;
921 } 1055 }
1056 if (ci->laddress == NULL)
1057 match_test_missing_fatal("LocalAddress",
1058 "laddr");
922 switch (addr_match_list(ci->laddress, arg)) { 1059 switch (addr_match_list(ci->laddress, arg)) {
923 case 1: 1060 case 1:
924 debug("connection from %.100s matched " 1061 debug("connection from %.100s matched "
@@ -938,10 +1075,12 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
938 arg); 1075 arg);
939 return -1; 1076 return -1;
940 } 1077 }
941 if (ci == NULL || ci->lport == 0) { 1078 if (ci == NULL) {
942 result = 0; 1079 result = 0;
943 continue; 1080 continue;
944 } 1081 }
1082 if (ci->lport == 0)
1083 match_test_missing_fatal("LocalPort", "lport");
945 /* TODO support port lists */ 1084 /* TODO support port lists */
946 if (port == ci->lport) 1085 if (port == ci->lport)
947 debug("connection from %.100s matched " 1086 debug("connection from %.100s matched "
@@ -949,6 +1088,16 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
949 ci->laddress, port, line); 1088 ci->laddress, port, line);
950 else 1089 else
951 result = 0; 1090 result = 0;
1091 } else if (strcasecmp(attrib, "rdomain") == 0) {
1092 if (ci == NULL || ci->rdomain == NULL) {
1093 result = 0;
1094 continue;
1095 }
1096 if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1097 result = 0;
1098 else
1099 debug("user %.100s matched 'RDomain %.100s' at "
1100 "line %d", ci->rdomain, arg, line);
952 } else { 1101 } else {
953 error("Unsupported Match attribute %s", attrib); 1102 error("Unsupported Match attribute %s", attrib);
954 return -1; 1103 return -1;
@@ -971,6 +1120,11 @@ struct multistate {
971 char *key; 1120 char *key;
972 int value; 1121 int value;
973}; 1122};
1123static const struct multistate multistate_flag[] = {
1124 { "yes", 1 },
1125 { "no", 0 },
1126 { NULL, -1 }
1127};
974static const struct multistate multistate_addressfamily[] = { 1128static const struct multistate multistate_addressfamily[] = {
975 { "inet", AF_INET }, 1129 { "inet", AF_INET },
976 { "inet6", AF_INET6 }, 1130 { "inet6", AF_INET6 },
@@ -1020,6 +1174,7 @@ process_server_config_line(ServerOptions *options, char *line,
1020 size_t len; 1174 size_t len;
1021 long long val64; 1175 long long val64;
1022 const struct multistate *multistate_ptr; 1176 const struct multistate *multistate_ptr;
1177 const char *errstr;
1023 1178
1024 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ 1179 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1025 if ((len = strlen(line)) == 0) 1180 if ((len = strlen(line)) == 0)
@@ -1107,20 +1262,33 @@ process_server_config_line(ServerOptions *options, char *line,
1107 /* check for bare IPv6 address: no "[]" and 2 or more ":" */ 1262 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
1108 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL 1263 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1109 && strchr(p+1, ':') != NULL) { 1264 && strchr(p+1, ':') != NULL) {
1110 queue_listen_addr(options, arg, 0);
1111 break;
1112 }
1113 p = hpdelim(&arg);
1114 if (p == NULL)
1115 fatal("%s line %d: bad address:port usage",
1116 filename, linenum);
1117 p = cleanhostname(p);
1118 if (arg == NULL)
1119 port = 0; 1265 port = 0;
1120 else if ((port = a2port(arg)) <= 0) 1266 p = arg;
1121 fatal("%s line %d: bad port number", filename, linenum); 1267 } else {
1268 p = hpdelim(&arg);
1269 if (p == NULL)
1270 fatal("%s line %d: bad address:port usage",
1271 filename, linenum);
1272 p = cleanhostname(p);
1273 if (arg == NULL)
1274 port = 0;
1275 else if ((port = a2port(arg)) <= 0)
1276 fatal("%s line %d: bad port number",
1277 filename, linenum);
1278 }
1279 /* Optional routing table */
1280 arg2 = NULL;
1281 if ((arg = strdelim(&cp)) != NULL) {
1282 if (strcmp(arg, "rdomain") != 0 ||
1283 (arg2 = strdelim(&cp)) == NULL)
1284 fatal("%s line %d: bad ListenAddress syntax",
1285 filename, linenum);
1286 if (!valid_rdomain(arg2))
1287 fatal("%s line %d: bad routing domain",
1288 filename, linenum);
1289 }
1122 1290
1123 queue_listen_addr(options, p, port); 1291 queue_listen_addr(options, p, arg2, port);
1124 1292
1125 break; 1293 break;
1126 1294
@@ -1147,22 +1315,12 @@ process_server_config_line(ServerOptions *options, char *line,
1147 break; 1315 break;
1148 1316
1149 case sHostKeyFile: 1317 case sHostKeyFile:
1150 intptr = &options->num_host_key_files;
1151 if (*intptr >= MAX_HOSTKEYS)
1152 fatal("%s line %d: too many host keys specified (max %d).",
1153 filename, linenum, MAX_HOSTKEYS);
1154 charptr = &options->host_key_files[*intptr];
1155 parse_filename:
1156 arg = strdelim(&cp); 1318 arg = strdelim(&cp);
1157 if (!arg || *arg == '\0') 1319 if (!arg || *arg == '\0')
1158 fatal("%s line %d: missing file name.", 1320 fatal("%s line %d: missing file name.",
1159 filename, linenum); 1321 filename, linenum);
1160 if (*activep && *charptr == NULL) { 1322 if (*activep)
1161 *charptr = derelativise_path(arg); 1323 servconf_add_hostkey(filename, linenum, options, arg);
1162 /* increase optional counter */
1163 if (intptr != NULL)
1164 *intptr = *intptr + 1;
1165 }
1166 break; 1324 break;
1167 1325
1168 case sHostKeyAgent: 1326 case sHostKeyAgent:
@@ -1177,17 +1335,28 @@ process_server_config_line(ServerOptions *options, char *line,
1177 break; 1335 break;
1178 1336
1179 case sHostCertificate: 1337 case sHostCertificate:
1180 intptr = &options->num_host_cert_files; 1338 arg = strdelim(&cp);
1181 if (*intptr >= MAX_HOSTKEYS) 1339 if (!arg || *arg == '\0')
1182 fatal("%s line %d: too many host certificates " 1340 fatal("%s line %d: missing file name.",
1183 "specified (max %d).", filename, linenum, 1341 filename, linenum);
1184 MAX_HOSTCERTS); 1342 if (*activep)
1185 charptr = &options->host_cert_files[*intptr]; 1343 servconf_add_hostcert(filename, linenum, options, arg);
1186 goto parse_filename; 1344 break;
1187 1345
1188 case sPidFile: 1346 case sPidFile:
1189 charptr = &options->pid_file; 1347 charptr = &options->pid_file;
1190 goto parse_filename; 1348 parse_filename:
1349 arg = strdelim(&cp);
1350 if (!arg || *arg == '\0')
1351 fatal("%s line %d: missing file name.",
1352 filename, linenum);
1353 if (*activep && *charptr == NULL) {
1354 *charptr = derelativise_path(arg);
1355 /* increase optional counter */
1356 if (intptr != NULL)
1357 *intptr = *intptr + 1;
1358 }
1359 break;
1191 1360
1192 case sPermitRootLogin: 1361 case sPermitRootLogin:
1193 intptr = &options->permit_root_login; 1362 intptr = &options->permit_root_login;
@@ -1197,21 +1366,8 @@ process_server_config_line(ServerOptions *options, char *line,
1197 case sIgnoreRhosts: 1366 case sIgnoreRhosts:
1198 intptr = &options->ignore_rhosts; 1367 intptr = &options->ignore_rhosts;
1199 parse_flag: 1368 parse_flag:
1200 arg = strdelim(&cp); 1369 multistate_ptr = multistate_flag;
1201 if (!arg || *arg == '\0') 1370 goto parse_multistate;
1202 fatal("%s line %d: missing yes/no argument.",
1203 filename, linenum);
1204 value = 0; /* silence compiler */
1205 if (strcmp(arg, "yes") == 0)
1206 value = 1;
1207 else if (strcmp(arg, "no") == 0)
1208 value = 0;
1209 else
1210 fatal("%s line %d: Bad yes/no argument: %s",
1211 filename, linenum, arg);
1212 if (*activep && *intptr == -1)
1213 *intptr = value;
1214 break;
1215 1371
1216 case sIgnoreUserKnownHosts: 1372 case sIgnoreUserKnownHosts:
1217 intptr = &options->ignore_user_known_hosts; 1373 intptr = &options->ignore_user_known_hosts;
@@ -1316,10 +1472,9 @@ process_server_config_line(ServerOptions *options, char *line,
1316 intptr = &options->x11_display_offset; 1472 intptr = &options->x11_display_offset;
1317 parse_int: 1473 parse_int:
1318 arg = strdelim(&cp); 1474 arg = strdelim(&cp);
1319 if (!arg || *arg == '\0') 1475 if ((errstr = atoi_err(arg, &value)) != NULL)
1320 fatal("%s line %d: missing integer value.", 1476 fatal("%s line %d: integer value %s.",
1321 filename, linenum); 1477 filename, linenum, errstr);
1322 value = atoi(arg);
1323 if (*activep && *intptr == -1) 1478 if (*activep && *intptr == -1)
1324 *intptr = value; 1479 *intptr = value;
1325 break; 1480 break;
@@ -1439,55 +1594,47 @@ process_server_config_line(ServerOptions *options, char *line,
1439 1594
1440 case sAllowUsers: 1595 case sAllowUsers:
1441 while ((arg = strdelim(&cp)) && *arg != '\0') { 1596 while ((arg = strdelim(&cp)) && *arg != '\0') {
1442 if (options->num_allow_users >= MAX_ALLOW_USERS)
1443 fatal("%s line %d: too many allow users.",
1444 filename, linenum);
1445 if (match_user(NULL, NULL, NULL, arg) == -1) 1597 if (match_user(NULL, NULL, NULL, arg) == -1)
1446 fatal("%s line %d: invalid AllowUsers pattern: " 1598 fatal("%s line %d: invalid AllowUsers pattern: "
1447 "\"%.100s\"", filename, linenum, arg); 1599 "\"%.100s\"", filename, linenum, arg);
1448 if (!*activep) 1600 if (!*activep)
1449 continue; 1601 continue;
1450 options->allow_users[options->num_allow_users++] = 1602 array_append(filename, linenum, "AllowUsers",
1451 xstrdup(arg); 1603 &options->allow_users, &options->num_allow_users,
1604 arg);
1452 } 1605 }
1453 break; 1606 break;
1454 1607
1455 case sDenyUsers: 1608 case sDenyUsers:
1456 while ((arg = strdelim(&cp)) && *arg != '\0') { 1609 while ((arg = strdelim(&cp)) && *arg != '\0') {
1457 if (options->num_deny_users >= MAX_DENY_USERS)
1458 fatal("%s line %d: too many deny users.",
1459 filename, linenum);
1460 if (match_user(NULL, NULL, NULL, arg) == -1) 1610 if (match_user(NULL, NULL, NULL, arg) == -1)
1461 fatal("%s line %d: invalid DenyUsers pattern: " 1611 fatal("%s line %d: invalid DenyUsers pattern: "
1462 "\"%.100s\"", filename, linenum, arg); 1612 "\"%.100s\"", filename, linenum, arg);
1463 if (!*activep) 1613 if (!*activep)
1464 continue; 1614 continue;
1465 options->deny_users[options->num_deny_users++] = 1615 array_append(filename, linenum, "DenyUsers",
1466 xstrdup(arg); 1616 &options->deny_users, &options->num_deny_users,
1617 arg);
1467 } 1618 }
1468 break; 1619 break;
1469 1620
1470 case sAllowGroups: 1621 case sAllowGroups:
1471 while ((arg = strdelim(&cp)) && *arg != '\0') { 1622 while ((arg = strdelim(&cp)) && *arg != '\0') {
1472 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1473 fatal("%s line %d: too many allow groups.",
1474 filename, linenum);
1475 if (!*activep) 1623 if (!*activep)
1476 continue; 1624 continue;
1477 options->allow_groups[options->num_allow_groups++] = 1625 array_append(filename, linenum, "AllowGroups",
1478 xstrdup(arg); 1626 &options->allow_groups, &options->num_allow_groups,
1627 arg);
1479 } 1628 }
1480 break; 1629 break;
1481 1630
1482 case sDenyGroups: 1631 case sDenyGroups:
1483 while ((arg = strdelim(&cp)) && *arg != '\0') { 1632 while ((arg = strdelim(&cp)) && *arg != '\0') {
1484 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1485 fatal("%s line %d: too many deny groups.",
1486 filename, linenum);
1487 if (!*activep) 1633 if (!*activep)
1488 continue; 1634 continue;
1489 options->deny_groups[options->num_deny_groups++] = 1635 array_append(filename, linenum, "DenyGroups",
1490 xstrdup(arg); 1636 &options->deny_groups, &options->num_deny_groups,
1637 arg);
1491 } 1638 }
1492 break; 1639 break;
1493 1640
@@ -1606,14 +1753,12 @@ process_server_config_line(ServerOptions *options, char *line,
1606 case sAuthorizedKeysFile: 1753 case sAuthorizedKeysFile:
1607 if (*activep && options->num_authkeys_files == 0) { 1754 if (*activep && options->num_authkeys_files == 0) {
1608 while ((arg = strdelim(&cp)) && *arg != '\0') { 1755 while ((arg = strdelim(&cp)) && *arg != '\0') {
1609 if (options->num_authkeys_files >= 1756 arg = tilde_expand_filename(arg, getuid());
1610 MAX_AUTHKEYS_FILES) 1757 array_append(filename, linenum,
1611 fatal("%s line %d: " 1758 "AuthorizedKeysFile",
1612 "too many authorized keys files.", 1759 &options->authorized_keys_files,
1613 filename, linenum); 1760 &options->num_authkeys_files, arg);
1614 options->authorized_keys_files[ 1761 free(arg);
1615 options->num_authkeys_files++] =
1616 tilde_expand_filename(arg, getuid());
1617 } 1762 }
1618 } 1763 }
1619 return 0; 1764 return 0;
@@ -1645,13 +1790,11 @@ process_server_config_line(ServerOptions *options, char *line,
1645 if (strchr(arg, '=') != NULL) 1790 if (strchr(arg, '=') != NULL)
1646 fatal("%s line %d: Invalid environment name.", 1791 fatal("%s line %d: Invalid environment name.",
1647 filename, linenum); 1792 filename, linenum);
1648 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1649 fatal("%s line %d: too many allow env.",
1650 filename, linenum);
1651 if (!*activep) 1793 if (!*activep)
1652 continue; 1794 continue;
1653 options->accept_env[options->num_accept_env++] = 1795 array_append(filename, linenum, "AcceptEnv",
1654 xstrdup(arg); 1796 &options->accept_env, &options->num_accept_env,
1797 arg);
1655 } 1798 }
1656 break; 1799 break;
1657 1800
@@ -1711,15 +1854,12 @@ process_server_config_line(ServerOptions *options, char *line,
1711 fatal("%s line %d: bad port number in " 1854 fatal("%s line %d: bad port number in "
1712 "PermitOpen", filename, linenum); 1855 "PermitOpen", filename, linenum);
1713 if (*activep && value == 0) { 1856 if (*activep && value == 0) {
1714 options->permitted_opens = xrecallocarray( 1857 array_append(filename, linenum,
1715 options->permitted_opens, 1858 "PermitOpen",
1716 options->num_permitted_opens, 1859 &options->permitted_opens,
1717 options->num_permitted_opens + 1, 1860 &options->num_permitted_opens, arg2);
1718 sizeof(*options->permitted_opens)); 1861 }
1719 i = options->num_permitted_opens++; 1862 free(arg2);
1720 options->permitted_opens[i] = arg2;
1721 } else
1722 free(arg2);
1723 } 1863 }
1724 break; 1864 break;
1725 1865
@@ -1842,11 +1982,6 @@ process_server_config_line(ServerOptions *options, char *line,
1842 value = 0; /* seen "any" pseudo-method */ 1982 value = 0; /* seen "any" pseudo-method */
1843 value2 = 0; /* sucessfully parsed any method */ 1983 value2 = 0; /* sucessfully parsed any method */
1844 while ((arg = strdelim(&cp)) && *arg != '\0') { 1984 while ((arg = strdelim(&cp)) && *arg != '\0') {
1845 if (options->num_auth_methods >=
1846 MAX_AUTH_METHODS)
1847 fatal("%s line %d: "
1848 "too many authentication methods.",
1849 filename, linenum);
1850 if (strcmp(arg, "any") == 0) { 1985 if (strcmp(arg, "any") == 0) {
1851 if (options->num_auth_methods > 0) { 1986 if (options->num_auth_methods > 0) {
1852 fatal("%s line %d: \"any\" " 1987 fatal("%s line %d: \"any\" "
@@ -1867,8 +2002,10 @@ process_server_config_line(ServerOptions *options, char *line,
1867 value2 = 1; 2002 value2 = 1;
1868 if (!*activep) 2003 if (!*activep)
1869 continue; 2004 continue;
1870 options->auth_methods[ 2005 array_append(filename, linenum,
1871 options->num_auth_methods++] = xstrdup(arg); 2006 "AuthenticationMethods",
2007 &options->auth_methods,
2008 &options->num_auth_methods, arg);
1872 } 2009 }
1873 if (value2 == 0) { 2010 if (value2 == 0) {
1874 fatal("%s line %d: no AuthenticationMethods " 2011 fatal("%s line %d: no AuthenticationMethods "
@@ -1910,9 +2047,23 @@ process_server_config_line(ServerOptions *options, char *line,
1910 intptr = &options->expose_userauth_info; 2047 intptr = &options->expose_userauth_info;
1911 goto parse_flag; 2048 goto parse_flag;
1912 2049
2050 case sRDomain:
2051 charptr = &options->routing_domain;
2052 arg = strdelim(&cp);
2053 if (!arg || *arg == '\0')
2054 fatal("%.200s line %d: Missing argument.",
2055 filename, linenum);
2056 if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2057 !valid_rdomain(arg))
2058 fatal("%s line %d: bad routing domain",
2059 filename, linenum);
2060 if (*activep && *charptr == NULL)
2061 *charptr = xstrdup(arg);
2062 break;
2063
1913 case sDebianBanner: 2064 case sDebianBanner:
1914 intptr = &options->debian_banner; 2065 intptr = &options->debian_banner;
1915 goto parse_int; 2066 goto parse_flag;
1916 2067
1917 case sDeprecated: 2068 case sDeprecated:
1918 case sIgnore: 2069 case sIgnore:
@@ -1994,6 +2145,8 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec)
1994 ci->user = xstrdup(p + 5); 2145 ci->user = xstrdup(p + 5);
1995 } else if (strncmp(p, "laddr=", 6) == 0) { 2146 } else if (strncmp(p, "laddr=", 6) == 0) {
1996 ci->laddress = xstrdup(p + 6); 2147 ci->laddress = xstrdup(p + 6);
2148 } else if (strncmp(p, "rdomain=", 8) == 0) {
2149 ci->rdomain = xstrdup(p + 8);
1997 } else if (strncmp(p, "lport=", 6) == 0) { 2150 } else if (strncmp(p, "lport=", 6) == 0) {
1998 ci->lport = a2port(p + 6); 2151 ci->lport = a2port(p + 6);
1999 if (ci->lport == -1) { 2152 if (ci->lport == -1) {
@@ -2011,19 +2164,6 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec)
2011} 2164}
2012 2165
2013/* 2166/*
2014 * returns 1 for a complete spec, 0 for partial spec and -1 for an
2015 * empty spec.
2016 */
2017int server_match_spec_complete(struct connection_info *ci)
2018{
2019 if (ci->user && ci->host && ci->address)
2020 return 1; /* complete */
2021 if (!ci->user && !ci->host && !ci->address)
2022 return -1; /* empty */
2023 return 0; /* partial */
2024}
2025
2026/*
2027 * Copy any supported values that are set. 2167 * Copy any supported values that are set.
2028 * 2168 *
2029 * If the preauth flag is set, we do not bother copying the string or 2169 * If the preauth flag is set, we do not bother copying the string or
@@ -2088,17 +2228,16 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2088 dst->n = src->n; \ 2228 dst->n = src->n; \
2089 } \ 2229 } \
2090} while(0) 2230} while(0)
2091#define M_CP_STRARRAYOPT(n, num_n) do {\ 2231#define M_CP_STRARRAYOPT(s, num_s) do {\
2092 if (src->num_n != 0) { \ 2232 u_int i; \
2093 for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ 2233 if (src->num_s != 0) { \
2094 dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ 2234 for (i = 0; i < dst->num_s; i++) \
2095 } \ 2235 free(dst->s[i]); \
2096} while(0) 2236 free(dst->s); \
2097#define M_CP_STRARRAYOPT_ALLOC(n, num_n) do { \ 2237 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2098 if (src->num_n != 0) { \ 2238 for (i = 0; i < src->num_s; i++) \
2099 dst->n = xcalloc(src->num_n, sizeof(*dst->n)); \ 2239 dst->s[i] = xstrdup(src->s[i]); \
2100 M_CP_STRARRAYOPT(n, num_n); \ 2240 dst->num_s = src->num_s; \
2101 dst->num_n = src->num_n; \
2102 } \ 2241 } \
2103} while(0) 2242} while(0)
2104 2243
@@ -2131,7 +2270,6 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2131#undef M_CP_INTOPT 2270#undef M_CP_INTOPT
2132#undef M_CP_STROPT 2271#undef M_CP_STROPT
2133#undef M_CP_STRARRAYOPT 2272#undef M_CP_STRARRAYOPT
2134#undef M_CP_STRARRAYOPT_ALLOC
2135 2273
2136void 2274void
2137parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, 2275parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
@@ -2262,45 +2400,61 @@ dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2262 printf("\n"); 2400 printf("\n");
2263} 2401}
2264 2402
2265void 2403static char *
2266dump_config(ServerOptions *o) 2404format_listen_addrs(struct listenaddr *la)
2267{ 2405{
2268 u_int i; 2406 int r;
2269 int ret;
2270 struct addrinfo *ai; 2407 struct addrinfo *ai;
2271 char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; 2408 char addr[NI_MAXHOST], port[NI_MAXSERV];
2272 char *laddr1 = xstrdup(""), *laddr2 = NULL; 2409 char *laddr1 = xstrdup(""), *laddr2 = NULL;
2273 2410
2274 /* these are usually at the top of the config */
2275 for (i = 0; i < o->num_ports; i++)
2276 printf("port %d\n", o->ports[i]);
2277 dump_cfg_fmtint(sAddressFamily, o->address_family);
2278
2279 /* 2411 /*
2280 * ListenAddress must be after Port. add_one_listen_addr pushes 2412 * ListenAddress must be after Port. add_one_listen_addr pushes
2281 * addresses onto a stack, so to maintain ordering we need to 2413 * addresses onto a stack, so to maintain ordering we need to
2282 * print these in reverse order. 2414 * print these in reverse order.
2283 */ 2415 */
2284 for (ai = o->listen_addrs; ai; ai = ai->ai_next) { 2416 for (ai = la->addrs; ai; ai = ai->ai_next) {
2285 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, 2417 if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2286 sizeof(addr), port, sizeof(port), 2418 sizeof(addr), port, sizeof(port),
2287 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 2419 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2288 error("getnameinfo failed: %.100s", 2420 error("getnameinfo: %.100s", ssh_gai_strerror(r));
2289 (ret != EAI_SYSTEM) ? gai_strerror(ret) : 2421 continue;
2290 strerror(errno)); 2422 }
2423 laddr2 = laddr1;
2424 if (ai->ai_family == AF_INET6) {
2425 xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2426 addr, port,
2427 la->rdomain == NULL ? "" : " rdomain ",
2428 la->rdomain == NULL ? "" : la->rdomain,
2429 laddr2);
2291 } else { 2430 } else {
2292 laddr2 = laddr1; 2431 xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2293 if (ai->ai_family == AF_INET6) 2432 addr, port,
2294 xasprintf(&laddr1, "listenaddress [%s]:%s\n%s", 2433 la->rdomain == NULL ? "" : " rdomain ",
2295 addr, port, laddr2); 2434 la->rdomain == NULL ? "" : la->rdomain,
2296 else 2435 laddr2);
2297 xasprintf(&laddr1, "listenaddress %s:%s\n%s",
2298 addr, port, laddr2);
2299 free(laddr2);
2300 } 2436 }
2437 free(laddr2);
2438 }
2439 return laddr1;
2440}
2441
2442void
2443dump_config(ServerOptions *o)
2444{
2445 char *s;
2446 u_int i;
2447
2448 /* these are usually at the top of the config */
2449 for (i = 0; i < o->num_ports; i++)
2450 printf("port %d\n", o->ports[i]);
2451 dump_cfg_fmtint(sAddressFamily, o->address_family);
2452
2453 for (i = 0; i < o->num_listen_addrs; i++) {
2454 s = format_listen_addrs(&o->listen_addrs[i]);
2455 printf("%s", s);
2456 free(s);
2301 } 2457 }
2302 printf("%s", laddr1);
2303 free(laddr1);
2304 2458
2305 /* integer arguments */ 2459 /* integer arguments */
2306#ifdef USE_PAM 2460#ifdef USE_PAM
@@ -2392,6 +2546,7 @@ dump_config(ServerOptions *o)
2392 o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); 2546 o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2393 dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? 2547 dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
2394 o->pubkey_key_types : KEX_DEFAULT_PK_ALG); 2548 o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2549 dump_cfg_string(sRDomain, o->routing_domain);
2395 2550
2396 /* string arguments requiring a lookup */ 2551 /* string arguments requiring a lookup */
2397 dump_cfg_string(sLogLevel, log_level_name(o->log_level)); 2552 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
@@ -2420,11 +2575,13 @@ dump_config(ServerOptions *o)
2420 printf("maxstartups %d:%d:%d\n", o->max_startups_begin, 2575 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
2421 o->max_startups_rate, o->max_startups); 2576 o->max_startups_rate, o->max_startups);
2422 2577
2423 for (i = 0; tunmode_desc[i].val != -1; i++) 2578 s = NULL;
2579 for (i = 0; tunmode_desc[i].val != -1; i++) {
2424 if (tunmode_desc[i].val == o->permit_tun) { 2580 if (tunmode_desc[i].val == o->permit_tun) {
2425 s = tunmode_desc[i].text; 2581 s = tunmode_desc[i].text;
2426 break; 2582 break;
2427 } 2583 }
2584 }
2428 dump_cfg_string(sPermitTunnel, s); 2585 dump_cfg_string(sPermitTunnel, s);
2429 2586
2430 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2587 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));