]> andersk Git - openssh.git/commitdiff
- dtucker@cvs.openbsd.org 2008/06/10 04:50:25
authordtucker <dtucker>
Tue, 10 Jun 2008 13:01:51 +0000 (13:01 +0000)
committerdtucker <dtucker>
Tue, 10 Jun 2008 13:01:51 +0000 (13:01 +0000)
     [sshd.c channels.h channels.c log.c servconf.c log.h servconf.h sshd.8]
     Add extended test mode (-T) and connection parameters for test mode (-C).
     -T causes sshd to write its effective configuration to stdout and exit.
     -C causes any relevant Match rules to be applied before output.  The
     combination allows tesing of the parser and config files.  ok deraadt djm

ChangeLog
channels.c
channels.h
log.c
log.h
servconf.c
servconf.h
sshd.8
sshd.c

index 2fa7e7dd201713b69644a9c3a09729c5b21a1d43..99ae4063135e263d8d0d6d65f80c6f7d633c6b22 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
    - djm@cvs.openbsd.org 2008/06/10 04:17:46
      [sshd_config.5]
      better reference for pattern-list
+   - dtucker@cvs.openbsd.org 2008/06/10 04:50:25
+     [sshd.c channels.h channels.c log.c servconf.c log.h servconf.h sshd.8]
+     Add extended test mode (-T) and connection parameters for test mode (-C).
+     -T causes sshd to write its effective configuration to stdout and exit.
+     -C causes any relevant Match rules to be applied before output.  The
+     combination allows tesing of the parser and config files.  ok deraadt djm
 
 20080609
  - (dtucker) OpenBSD CVS Sync
index 99b23d75fc1de41ca11dae4fb961df591db52f90..6808d3a05f1ef6c0616c3171944246790c0d196d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.277 2008/05/09 16:17:51 markus Exp $ */
+/* $OpenBSD: channels.c,v 1.278 2008/06/10 04:50:25 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2784,6 +2784,17 @@ channel_clear_adm_permitted_opens(void)
        num_adm_permitted_opens = 0;
 }
 
+void
+channel_print_adm_permitted_opens(void)
+{
+       static int i;
+
+       for (i = 0; i < num_adm_permitted_opens; i++)
+               if (permitted_adm_opens[i].host_to_connect != NULL)
+                       printf(" %s:%d", permitted_adm_opens[i].host_to_connect,
+                           permitted_adm_opens[i].port_to_connect);
+}
+
 /* Try to start non-blocking connect to next host in cctx list */
 static int
 connect_next(struct channel_connect *cctx)
index ec2435df0dc1f9b24e5e3b003177d55d774b20de..dc1f483ed37017e6722ca5df84839d6010439203 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.92 2008/05/09 16:21:13 markus Exp $ */
+/* $OpenBSD: channels.h,v 1.93 2008/06/10 04:50:25 dtucker Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -235,6 +235,7 @@ void         channel_add_permitted_opens(char *, int);
 int     channel_add_adm_permitted_opens(char *, int);
 void    channel_clear_permitted_opens(void);
 void    channel_clear_adm_permitted_opens(void);
+void    channel_print_adm_permitted_opens(void);
 int      channel_input_port_forward_request(int, int);
 Channel        *channel_connect_to(const char *, u_short, char *, char *);
 Channel        *channel_connect_by_listen_address(u_short, char *, char *);
diff --git a/log.c b/log.c
index fae5b043f3e55701a9ca1d8a99aa9791e2513bff..4a8239b931de474319b3cb21420eedbfaaeccc30 100644 (file)
--- a/log.c
+++ b/log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.c,v 1.40 2007/05/17 07:50:31 djm Exp $ */
+/* $OpenBSD: log.c,v 1.41 2008/06/10 04:50:25 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -114,6 +114,17 @@ log_facility_number(char *name)
        return SYSLOG_FACILITY_NOT_SET;
 }
 
+const char *
+log_facility_name(SyslogFacility facility)
+{
+       u_int i;
+
+       for (i = 0;  log_facilities[i].name; i++)
+               if (log_facilities[i].val == facility)
+                       return log_facilities[i].name;
+       return NULL;
+}
+
 LogLevel
 log_level_number(char *name)
 {
@@ -126,6 +137,17 @@ log_level_number(char *name)
        return SYSLOG_LEVEL_NOT_SET;
 }
 
+const char *
+log_level_name(LogLevel level)
+{
+       u_int i;
+
+       for (i = 0; log_levels[i].name != NULL; i++)
+               if (log_levels[i].val == level)
+                       return log_levels[i].name;
+       return NULL;
+}
+
 /* Error messages that should be logged. */
 
 void
diff --git a/log.h b/log.h
index 7a8c57079cca6242938bc18ce901143c5996be43..fa0996ad59d4fcd863205c855672aee7296a98f7 100644 (file)
--- a/log.h
+++ b/log.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.h,v 1.15 2006/08/18 09:13:25 deraadt Exp $ */
+/* $OpenBSD: log.h,v 1.16 2008/06/10 04:50:25 dtucker Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -49,7 +49,9 @@ typedef enum {
 void     log_init(char *, LogLevel, SyslogFacility, int);
 
 SyslogFacility log_facility_number(char *);
-LogLevel log_level_number(char *);
+const char *   log_facility_name(SyslogFacility);
+LogLevel       log_level_number(char *);
+const char *   log_level_name(LogLevel);
 
 void     fatal(const char *, ...) __dead __attribute__((format(printf, 1, 2)));
 void     error(const char *, ...) __attribute__((format(printf, 1, 2)));
index 07a201034ecd5c62068249e8dc6599fbe0ef8b57..63704fb33ced16e88efa49a8a52fc344a2378a93 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.181 2008/06/10 03:57:27 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.182 2008/06/10 04:50:25 dtucker Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -23,6 +23,7 @@
 #include <signal.h>
 #include <unistd.h>
 #include <stdarg.h>
+#include <errno.h>
 
 #include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
@@ -417,6 +418,17 @@ static struct {
        { NULL, sBadOption, 0 }
 };
 
+static struct {
+       int val;
+       char *text;
+} tunmode_desc[] = {
+       { SSH_TUNMODE_NO, "no" },
+       { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
+       { SSH_TUNMODE_ETHERNET, "ethernet" },
+       { SSH_TUNMODE_YES, "yes" },
+       { -1, NULL }
+};
+
 /*
  * Returns the number of the token pointed to by cp or sBadOption.
  */
@@ -1211,16 +1223,13 @@ process_server_config_line(ServerOptions *options, char *line,
                if (!arg || *arg == '\0')
                        fatal("%s line %d: Missing yes/point-to-point/"
                            "ethernet/no argument.", filename, linenum);
-               value = 0;      /* silence compiler */
-               if (strcasecmp(arg, "ethernet") == 0)
-                       value = SSH_TUNMODE_ETHERNET;
-               else if (strcasecmp(arg, "point-to-point") == 0)
-                       value = SSH_TUNMODE_POINTOPOINT;
-               else if (strcasecmp(arg, "yes") == 0)
-                       value = SSH_TUNMODE_YES;
-               else if (strcasecmp(arg, "no") == 0)
-                       value = SSH_TUNMODE_NO;
-               else
+               value = -1;
+               for (i = 0; tunmode_desc[i].val != -1; i++)
+                       if (strcmp(tunmode_desc[i].text, arg) == 0) {
+                               value = tunmode_desc[i].val;
+                               break;
+                       }
+               if (value == -1)
                        fatal("%s line %d: Bad yes/point-to-point/ethernet/"
                            "no argument: %s", filename, linenum, arg);
                if (*intptr == -1)
@@ -1426,3 +1435,213 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
                fatal("%s: terminating, %d bad configuration options",
                    filename, bad_options);
 }
+
+static const char *
+fmt_intarg(ServerOpCodes code, int val)
+{
+       if (code == sAddressFamily) {
+               switch (val) {
+               case AF_INET:
+                       return "inet";
+               case AF_INET6:
+                       return "inet6";
+               case AF_UNSPEC:
+                       return "any";
+               default:
+                       return "UNKNOWN";
+               }
+       }
+       if (code == sPermitRootLogin) {
+               switch (val) {
+               case PERMIT_NO_PASSWD:
+                       return "without-passord";
+               case PERMIT_FORCED_ONLY:
+                       return "forced-commands-only";
+               case PERMIT_YES:
+                       return "yes";
+               }
+       }
+       if (code == sProtocol) {
+               switch (val) {
+               case SSH_PROTO_1:
+                       return "1";
+               case SSH_PROTO_2:
+                       return "2";
+               case (SSH_PROTO_1|SSH_PROTO_2):
+                       return "2,1";
+               default:
+                       return "UNKNOWN";
+               }
+       }
+       if (code == sGatewayPorts && val == 2)
+               return "clientspecified";
+       if (code == sCompression && val == COMP_DELAYED)
+               return "delayed";
+       switch (val) {
+       case -1:
+               return "unset";
+       case 0:
+               return "no";
+       case 1:
+               return "yes";
+       }
+       return "UNKNOWN";
+}
+
+static const char *
+lookup_opcode_name(ServerOpCodes code)
+{
+       u_int i;
+
+       for (i = 0; keywords[i].name != NULL; i++)
+               if (keywords[i].opcode == code)
+                       return(keywords[i].name);
+       return "UNKNOWN";
+}
+
+static void
+dump_cfg_int(ServerOpCodes code, int val)
+{
+       printf("%s %d\n", lookup_opcode_name(code), val);
+}
+
+static void
+dump_cfg_fmtint(ServerOpCodes code, int val)
+{
+       printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
+}
+
+static void
+dump_cfg_string(ServerOpCodes code, const char *val)
+{
+       if (val == NULL)
+               return;
+       printf("%s %s\n", lookup_opcode_name(code), val);
+}
+
+static void
+dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
+{
+       u_int i;
+
+       for (i = 0; i < count; i++)
+               printf("%s %s\n", lookup_opcode_name(code),  vals[i]);
+}
+
+void
+dump_config(ServerOptions *o)
+{
+       u_int i;
+       int ret;
+       struct addrinfo *ai;
+       char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
+
+       /* these are usually at the top of the config */
+       for (i = 0; i < o->num_ports; i++)
+               printf("port %d\n", o->ports[i]);
+       dump_cfg_fmtint(sProtocol, o->protocol);
+       dump_cfg_fmtint(sAddressFamily, o->address_family);
+
+       /* ListenAddress must be after Port */
+       for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
+               if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
+                   sizeof(addr), port, sizeof(port),
+                   NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
+                       error("getnameinfo failed: %.100s",
+                           (ret != EAI_SYSTEM) ? gai_strerror(ret) :
+                           strerror(errno));
+               } else {
+                       if (ai->ai_family == AF_INET6)
+                               printf("listenaddress [%s]:%s\n", addr, port);
+                       else
+                               printf("listenaddress %s:%s\n", addr, port);
+               }
+       }
+
+       /* integer arguments */
+       dump_cfg_int(sServerKeyBits, o->server_key_bits);
+       dump_cfg_int(sLoginGraceTime, o->login_grace_time);
+       dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
+       dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
+       dump_cfg_int(sMaxAuthTries, o->max_authtries);
+       dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
+       dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
+
+       /* formatted integer arguments */
+       dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
+       dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
+       dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
+       dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
+       dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
+       dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
+           o->hostbased_uses_name_from_packet_only);
+       dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
+       dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
+       dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
+       dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
+       dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
+       dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
+       dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
+       dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
+       dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
+       dump_cfg_fmtint(sKbdInteractiveAuthentication,
+           o->kbd_interactive_authentication);
+       dump_cfg_fmtint(sChallengeResponseAuthentication,
+           o->challenge_response_authentication);
+       dump_cfg_fmtint(sPrintMotd, o->print_motd);
+       dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
+       dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
+       dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
+       dump_cfg_fmtint(sStrictModes, o->strict_modes);
+       dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
+       dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
+       dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
+       dump_cfg_fmtint(sUseLogin, o->use_login);
+       dump_cfg_fmtint(sCompression, o->compression);
+       dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
+       dump_cfg_fmtint(sUseDNS, o->use_dns);
+       dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
+       dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
+
+       /* string arguments */
+       dump_cfg_string(sPidFile, o->pid_file);
+       dump_cfg_string(sXAuthLocation, o->xauth_location);
+       dump_cfg_string(sCiphers, o->ciphers);
+       dump_cfg_string(sMacs, o->macs);
+       dump_cfg_string(sBanner, o->banner);
+       dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
+       dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
+       dump_cfg_string(sForceCommand, o->adm_forced_command);
+
+       /* string arguments requiring a lookup */
+       dump_cfg_string(sLogLevel, log_level_name(o->log_level));
+       dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
+
+       /* string array arguments */
+       dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
+            o->host_key_files);
+       dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
+       dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
+       dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
+       dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
+       dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
+
+       /* other arguments */
+       for (i = 0; i < o->num_subsystems; i++)
+               printf("subsystem %s %s\n", o->subsystem_name[i],
+                   o->subsystem_args[i]);
+
+       printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
+           o->max_startups_rate, o->max_startups);
+
+       for (i = 0; tunmode_desc[i].val != -1; i++)
+               if (tunmode_desc[i].val == o->permit_tun) {
+                       s = tunmode_desc[i].text;
+                       break;
+               }
+       dump_cfg_string(sPermitTunnel, s);
+
+       printf("permitopen");
+       channel_print_adm_permitted_opens();
+       printf("\n");
+}
index 819a028c8a88b52e028e51e3bb85c2f5444f1633..40ac64f135094b0afd95804b61eaf7b71082ded8 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.84 2008/05/08 12:21:16 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.85 2008/06/10 04:50:25 dtucker Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -161,5 +161,6 @@ void         parse_server_config(ServerOptions *, const char *, Buffer *,
 void    parse_server_match_config(ServerOptions *, const char *, const char *,
             const char *);
 void    copy_set_server_options(ServerOptions *, ServerOptions *, int);
+void    dump_config(ServerOptions *);
 
 #endif                         /* SERVCONF_H */
diff --git a/sshd.8 b/sshd.8
index 8cf9420c65358f0fced8de6829f606b73419b752..d6535dd6d1c1649ed1e804b2702ba69e8051c575 100644 (file)
--- a/sshd.8
+++ b/sshd.8
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd.8,v 1.241 2008/03/27 22:37:57 jmc Exp $
+.\" $OpenBSD: sshd.8,v 1.242 2008/06/10 04:50:25 dtucker Exp $
 .Dd $Mdocdate$
 .Dt SSHD 8
 .Os
@@ -44,8 +44,9 @@
 .Sh SYNOPSIS
 .Nm sshd
 .Bk -words
-.Op Fl 46Ddeiqt
+.Op Fl 46DTdeiqt
 .Op Fl b Ar bits
+.Op Fl C Ar connection_spec
 .Op Fl f Ar config_file
 .Op Fl g Ar login_grace_time
 .Op Fl h Ar host_key_file
@@ -197,6 +198,33 @@ Only check the validity of the configuration file and sanity of the keys.
 This is useful for updating
 .Nm
 reliably as configuration options may change.
+.It Fl T
+Extended test mode.
+Check the validity of the configuration file, output the effective configuration
+to stdout and then exit.
+Optionally,
+.Cm Match
+rules may be applied by specifying the connection parameters using one or more
+.Fl C
+options.
+.It Fl C
+Specify the connection parameters to use for the the
+.Fl T
+extended test mode.
+If provided, any
+.Cm Match
+directives in the configuration file
+that would apply to the specified user, host and address will be set before
+the configuration is written to standard output.
+The connection parameters are supplied as keyword=value pairs.
+The keywords are
+.Dq user ,
+.Dq host
+and 
+.Dq addr
+All are required and may be supplied in any order, either with multiple
+.Fl C
+options or as a comma-separated list.
 .It Fl u Ar len
 This option is used to specify the size of the field
 in the
diff --git a/sshd.c b/sshd.c
index aefbaaa421ce837fd68e54eff24d877f09915757..ccff65d060596acdaaea9c01ebab3b5fb3f2e761 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.357 2008/05/08 12:02:23 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.358 2008/06/10 04:50:25 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1240,8 +1240,9 @@ main(int ac, char **av)
        int opt, i, on = 1;
        int sock_in = -1, sock_out = -1, newsock = -1;
        const char *remote_ip;
+       char *test_user = NULL, *test_host = NULL, *test_addr = NULL;
        int remote_port;
-       char *line;
+       char *line, *p, *cp;
        int config_s[2] = { -1 , -1 };
        Key *key;
        Authctxt *authctxt;
@@ -1276,7 +1277,7 @@ main(int ac, char **av)
        initialize_server_options(&options);
 
        /* Parse command-line arguments. */
-       while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) {
+       while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) {
                switch (opt) {
                case '4':
                        options.address_family = AF_INET;
@@ -1354,6 +1355,25 @@ main(int ac, char **av)
                case 't':
                        test_flag = 1;
                        break;
+               case 'T':
+                       test_flag = 2;
+                       break;
+               case 'C':
+                       cp = optarg;
+                       while ((p = strsep(&cp, ",")) && *p != '\0') {
+                               if (strncmp(p, "addr=", 5) == 0)
+                                       test_addr = xstrdup(p + 5);
+                               else if (strncmp(p, "host=", 5) == 0)
+                                       test_host = xstrdup(p + 5);
+                               else if (strncmp(p, "user=", 5) == 0)
+                                       test_user = xstrdup(p + 5);
+                               else {
+                                       fprintf(stderr, "Invalid test "
+                                           "mode specification %s\n", p);
+                                       exit(1);
+                               }
+                       }
+                       break;
                case 'u':
                        utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL);
                        if (utmp_len > MAXHOSTNAMELEN) {
@@ -1415,6 +1435,20 @@ main(int ac, char **av)
        sensitive_data.have_ssh1_key = 0;
        sensitive_data.have_ssh2_key = 0;
 
+       /*
+        * If we're doing an extended config test, make sure we have all of
+        * the parameters we need.  If we're not doing an extended test,
+        * do not silently ignore connection test params.
+        */
+       if (test_flag >= 2 && (test_user != NULL || test_host != NULL || test_addr != NULL)
+           && (test_user == NULL || test_host == NULL || test_addr == NULL))
+               fatal("user, host and addr are all required when testing "
+                  "Match configs");
+       if (test_flag < 2 && (test_user != NULL || test_host != NULL ||
+           test_addr != NULL))
+               fatal("Config test connection parameter (-C) provided without "
+                  "test mode (-T)");
+
        /* Fetch our configuration */
        buffer_init(&cfg);
        if (rexeced_flag)
@@ -1543,6 +1577,13 @@ main(int ac, char **av)
                            "world-writable.", _PATH_PRIVSEP_CHROOT_DIR);
        }
 
+       if (test_flag > 1) {
+               if (test_user != NULL && test_addr != NULL && test_host != NULL)
+                       parse_server_match_config(&options, test_user,
+                           test_host, test_addr);
+               dump_config(&options);
+       }
+
        /* Configuration looks good, so exit if in test mode. */
        if (test_flag)
                exit(0);
This page took 0.174805 seconds and 5 git commands to generate.