summaryrefslogtreecommitdiff
path: root/servconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'servconf.c')
-rw-r--r--servconf.c359
1 files changed, 301 insertions, 58 deletions
diff --git a/servconf.c b/servconf.c
index f56cc1803..ede032567 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.c,v 1.172 2007/04/23 10:15:39 dtucker Exp $ */ 1/* $OpenBSD: servconf.c,v 1.186 2008/07/04 03:44:59 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved 4 * All rights reserved
@@ -23,7 +23,9 @@
23#include <signal.h> 23#include <signal.h>
24#include <unistd.h> 24#include <unistd.h>
25#include <stdarg.h> 25#include <stdarg.h>
26#include <errno.h>
26 27
28#include "openbsd-compat/sys-queue.h"
27#include "xmalloc.h" 29#include "xmalloc.h"
28#include "ssh.h" 30#include "ssh.h"
29#include "log.h" 31#include "log.h"
@@ -101,6 +103,7 @@ initialize_server_options(ServerOptions *options)
101 options->use_login = -1; 103 options->use_login = -1;
102 options->compression = -1; 104 options->compression = -1;
103 options->allow_tcp_forwarding = -1; 105 options->allow_tcp_forwarding = -1;
106 options->allow_agent_forwarding = -1;
104 options->num_allow_users = 0; 107 options->num_allow_users = 0;
105 options->num_deny_users = 0; 108 options->num_deny_users = 0;
106 options->num_allow_groups = 0; 109 options->num_allow_groups = 0;
@@ -114,6 +117,7 @@ initialize_server_options(ServerOptions *options)
114 options->max_startups_rate = -1; 117 options->max_startups_rate = -1;
115 options->max_startups = -1; 118 options->max_startups = -1;
116 options->max_authtries = -1; 119 options->max_authtries = -1;
120 options->max_sessions = -1;
117 options->banner = NULL; 121 options->banner = NULL;
118 options->use_dns = -1; 122 options->use_dns = -1;
119 options->client_alive_interval = -1; 123 options->client_alive_interval = -1;
@@ -124,6 +128,7 @@ initialize_server_options(ServerOptions *options)
124 options->permit_tun = -1; 128 options->permit_tun = -1;
125 options->num_permitted_opens = -1; 129 options->num_permitted_opens = -1;
126 options->adm_forced_command = NULL; 130 options->adm_forced_command = NULL;
131 options->chroot_directory = NULL;
127} 132}
128 133
129void 134void
@@ -155,7 +160,7 @@ fill_default_server_options(ServerOptions *options)
155 if (options->pid_file == NULL) 160 if (options->pid_file == NULL)
156 options->pid_file = _PATH_SSH_DAEMON_PID_FILE; 161 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
157 if (options->server_key_bits == -1) 162 if (options->server_key_bits == -1)
158 options->server_key_bits = 768; 163 options->server_key_bits = 1024;
159 if (options->login_grace_time == -1) 164 if (options->login_grace_time == -1)
160 options->login_grace_time = 120; 165 options->login_grace_time = 120;
161 if (options->key_regeneration_time == -1) 166 if (options->key_regeneration_time == -1)
@@ -228,6 +233,8 @@ fill_default_server_options(ServerOptions *options)
228 options->compression = COMP_DELAYED; 233 options->compression = COMP_DELAYED;
229 if (options->allow_tcp_forwarding == -1) 234 if (options->allow_tcp_forwarding == -1)
230 options->allow_tcp_forwarding = 1; 235 options->allow_tcp_forwarding = 1;
236 if (options->allow_agent_forwarding == -1)
237 options->allow_agent_forwarding = 1;
231 if (options->gateway_ports == -1) 238 if (options->gateway_ports == -1)
232 options->gateway_ports = 0; 239 options->gateway_ports = 0;
233 if (options->max_startups == -1) 240 if (options->max_startups == -1)
@@ -238,6 +245,8 @@ fill_default_server_options(ServerOptions *options)
238 options->max_startups_begin = options->max_startups; 245 options->max_startups_begin = options->max_startups;
239 if (options->max_authtries == -1) 246 if (options->max_authtries == -1)
240 options->max_authtries = DEFAULT_AUTH_FAIL_MAX; 247 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
248 if (options->max_sessions == -1)
249 options->max_sessions = DEFAULT_SESSIONS_MAX;
241 if (options->use_dns == -1) 250 if (options->use_dns == -1)
242 options->use_dns = 1; 251 options->use_dns = 1;
243 if (options->client_alive_interval == -1) 252 if (options->client_alive_interval == -1)
@@ -292,15 +301,15 @@ typedef enum {
292 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 301 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
293 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 302 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
294 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, 303 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
295 sMaxStartups, sMaxAuthTries, 304 sMaxStartups, sMaxAuthTries, sMaxSessions,
296 sBanner, sUseDNS, sHostbasedAuthentication, 305 sBanner, sUseDNS, sHostbasedAuthentication,
297 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 306 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
298 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 307 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
299 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, 308 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
300 sGssKeyEx, 309 sGssKeyEx,
301 sAcceptEnv, sPermitTunnel, 310 sAcceptEnv, sPermitTunnel,
302 sMatch, sPermitOpen, sForceCommand, 311 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
303 sUsePrivilegeSeparation, 312 sUsePrivilegeSeparation, sAllowAgentForwarding,
304 sDeprecated, sUnsupported 313 sDeprecated, sUnsupported
305} ServerOpCodes; 314} ServerOpCodes;
306 315
@@ -329,7 +338,7 @@ static struct {
329 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, 338 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
330 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, 339 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
331 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, 340 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
332 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL }, 341 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
333 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, 342 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
334 { "loglevel", sLogLevel, SSHCFG_GLOBAL }, 343 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
335 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, 344 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
@@ -390,6 +399,7 @@ static struct {
390 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, 399 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
391 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ 400 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
392 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, 401 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
402 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
393 { "allowusers", sAllowUsers, SSHCFG_GLOBAL }, 403 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
394 { "denyusers", sDenyUsers, SSHCFG_GLOBAL }, 404 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
395 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL }, 405 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
@@ -400,7 +410,8 @@ static struct {
400 { "gatewayports", sGatewayPorts, SSHCFG_ALL }, 410 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
401 { "subsystem", sSubsystem, SSHCFG_GLOBAL }, 411 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
402 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, 412 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
403 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL }, 413 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
414 { "maxsessions", sMaxSessions, SSHCFG_ALL },
404 { "banner", sBanner, SSHCFG_ALL }, 415 { "banner", sBanner, SSHCFG_ALL },
405 { "usedns", sUseDNS, SSHCFG_GLOBAL }, 416 { "usedns", sUseDNS, SSHCFG_GLOBAL },
406 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, 417 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
@@ -415,9 +426,21 @@ static struct {
415 { "match", sMatch, SSHCFG_ALL }, 426 { "match", sMatch, SSHCFG_ALL },
416 { "permitopen", sPermitOpen, SSHCFG_ALL }, 427 { "permitopen", sPermitOpen, SSHCFG_ALL },
417 { "forcecommand", sForceCommand, SSHCFG_ALL }, 428 { "forcecommand", sForceCommand, SSHCFG_ALL },
429 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
418 { NULL, sBadOption, 0 } 430 { NULL, sBadOption, 0 }
419}; 431};
420 432
433static struct {
434 int val;
435 char *text;
436} tunmode_desc[] = {
437 { SSH_TUNMODE_NO, "no" },
438 { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
439 { SSH_TUNMODE_ETHERNET, "ethernet" },
440 { SSH_TUNMODE_YES, "yes" },
441 { -1, NULL }
442};
443
421/* 444/*
422 * Returns the number of the token pointed to by cp or sBadOption. 445 * Returns the number of the token pointed to by cp or sBadOption.
423 */ 446 */
@@ -470,7 +493,7 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
470 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 493 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
471 fatal("bad addr or host: %s (%s)", 494 fatal("bad addr or host: %s (%s)",
472 addr ? addr : "<NULL>", 495 addr ? addr : "<NULL>",
473 gai_strerror(gaierr)); 496 ssh_gai_strerror(gaierr));
474 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 497 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
475 ; 498 ;
476 ai->ai_next = options->listen_addrs; 499 ai->ai_next = options->listen_addrs;
@@ -514,24 +537,8 @@ static int
514match_cfg_line_group(const char *grps, int line, const char *user) 537match_cfg_line_group(const char *grps, int line, const char *user)
515{ 538{
516 int result = 0; 539 int result = 0;
517 u_int ngrps = 0;
518 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
519 struct passwd *pw; 540 struct passwd *pw;
520 541
521 /*
522 * Even if we do not have a user yet, we still need to check for
523 * valid syntax.
524 */
525 arg = cp = xstrdup(grps);
526 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
527 if (ngrps >= MAX_MATCH_GROUPS) {
528 error("line %d: too many groups in Match Group", line);
529 result = -1;
530 goto out;
531 }
532 grplist[ngrps++] = p;
533 }
534
535 if (user == NULL) 542 if (user == NULL)
536 goto out; 543 goto out;
537 544
@@ -541,17 +548,16 @@ match_cfg_line_group(const char *grps, int line, const char *user)
541 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 548 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
542 debug("Can't Match group because user %.100s not in any group " 549 debug("Can't Match group because user %.100s not in any group "
543 "at line %d", user, line); 550 "at line %d", user, line);
544 } else if (ga_match(grplist, ngrps) != 1) { 551 } else if (ga_match_pattern_list(grps) != 1) {
545 debug("user %.100s does not match group %.100s at line %d", 552 debug("user %.100s does not match group list %.100s at line %d",
546 user, arg, line); 553 user, grps, line);
547 } else { 554 } else {
548 debug("user %.100s matched group %.100s at line %d", user, 555 debug("user %.100s matched group list %.100s at line %d", user,
549 arg, line); 556 grps, line);
550 result = 1; 557 result = 1;
551 } 558 }
552out: 559out:
553 ga_free(); 560 ga_free();
554 xfree(arg);
555 return result; 561 return result;
556} 562}
557 563
@@ -604,15 +610,18 @@ match_cfg_line(char **condition, int line, const char *user, const char *host,
604 debug("connection from %.100s matched 'Host " 610 debug("connection from %.100s matched 'Host "
605 "%.100s' at line %d", host, arg, line); 611 "%.100s' at line %d", host, arg, line);
606 } else if (strcasecmp(attrib, "address") == 0) { 612 } else if (strcasecmp(attrib, "address") == 0) {
607 if (!address) { 613 switch (addr_match_list(address, arg)) {
608 result = 0; 614 case 1:
609 continue;
610 }
611 if (match_hostname(address, arg, len) != 1)
612 result = 0;
613 else
614 debug("connection from %.100s matched 'Address " 615 debug("connection from %.100s matched 'Address "
615 "%.100s' at line %d", address, arg, line); 616 "%.100s' at line %d", address, arg, line);
617 break;
618 case 0:
619 case -1:
620 result = 0;
621 break;
622 case -2:
623 return -1;
624 }
616 } else { 625 } else {
617 error("Unsupported Match attribute %s", attrib); 626 error("Unsupported Match attribute %s", attrib);
618 return -1; 627 return -1;
@@ -633,6 +642,8 @@ process_server_config_line(ServerOptions *options, char *line,
633{ 642{
634 char *cp, **charptr, *arg, *p; 643 char *cp, **charptr, *arg, *p;
635 int cmdline = 0, *intptr, value, n; 644 int cmdline = 0, *intptr, value, n;
645 SyslogFacility *log_facility_ptr;
646 LogLevel *log_level_ptr;
636 ServerOpCodes opcode; 647 ServerOpCodes opcode;
637 u_short port; 648 u_short port;
638 u_int i, flags = 0; 649 u_int i, flags = 0;
@@ -698,7 +709,7 @@ process_server_config_line(ServerOptions *options, char *line,
698 709
699 case sServerKeyBits: 710 case sServerKeyBits:
700 intptr = &options->server_key_bits; 711 intptr = &options->server_key_bits;
701parse_int: 712 parse_int:
702 arg = strdelim(&cp); 713 arg = strdelim(&cp);
703 if (!arg || *arg == '\0') 714 if (!arg || *arg == '\0')
704 fatal("%s line %d: missing integer value.", 715 fatal("%s line %d: missing integer value.",
@@ -710,7 +721,7 @@ parse_int:
710 721
711 case sLoginGraceTime: 722 case sLoginGraceTime:
712 intptr = &options->login_grace_time; 723 intptr = &options->login_grace_time;
713parse_time: 724 parse_time:
714 arg = strdelim(&cp); 725 arg = strdelim(&cp);
715 if (!arg || *arg == '\0') 726 if (!arg || *arg == '\0')
716 fatal("%s line %d: missing time value.", 727 fatal("%s line %d: missing time value.",
@@ -779,7 +790,7 @@ parse_time:
779 fatal("%s line %d: too many host keys specified (max %d).", 790 fatal("%s line %d: too many host keys specified (max %d).",
780 filename, linenum, MAX_HOSTKEYS); 791 filename, linenum, MAX_HOSTKEYS);
781 charptr = &options->host_key_files[*intptr]; 792 charptr = &options->host_key_files[*intptr];
782parse_filename: 793 parse_filename:
783 arg = strdelim(&cp); 794 arg = strdelim(&cp);
784 if (!arg || *arg == '\0') 795 if (!arg || *arg == '\0')
785 fatal("%s line %d: missing file name.", 796 fatal("%s line %d: missing file name.",
@@ -816,13 +827,13 @@ parse_filename:
816 fatal("%s line %d: Bad yes/" 827 fatal("%s line %d: Bad yes/"
817 "without-password/forced-commands-only/no " 828 "without-password/forced-commands-only/no "
818 "argument: %s", filename, linenum, arg); 829 "argument: %s", filename, linenum, arg);
819 if (*intptr == -1) 830 if (*activep && *intptr == -1)
820 *intptr = value; 831 *intptr = value;
821 break; 832 break;
822 833
823 case sIgnoreRhosts: 834 case sIgnoreRhosts:
824 intptr = &options->ignore_rhosts; 835 intptr = &options->ignore_rhosts;
825parse_flag: 836 parse_flag:
826 arg = strdelim(&cp); 837 arg = strdelim(&cp);
827 if (!arg || *arg == '\0') 838 if (!arg || *arg == '\0')
828 fatal("%s line %d: missing yes/no argument.", 839 fatal("%s line %d: missing yes/no argument.",
@@ -996,31 +1007,35 @@ parse_flag:
996 goto parse_flag; 1007 goto parse_flag;
997 1008
998 case sLogFacility: 1009 case sLogFacility:
999 intptr = (int *) &options->log_facility; 1010 log_facility_ptr = &options->log_facility;
1000 arg = strdelim(&cp); 1011 arg = strdelim(&cp);
1001 value = log_facility_number(arg); 1012 value = log_facility_number(arg);
1002 if (value == SYSLOG_FACILITY_NOT_SET) 1013 if (value == SYSLOG_FACILITY_NOT_SET)
1003 fatal("%.200s line %d: unsupported log facility '%s'", 1014 fatal("%.200s line %d: unsupported log facility '%s'",
1004 filename, linenum, arg ? arg : "<NONE>"); 1015 filename, linenum, arg ? arg : "<NONE>");
1005 if (*intptr == -1) 1016 if (*log_facility_ptr == -1)
1006 *intptr = (SyslogFacility) value; 1017 *log_facility_ptr = (SyslogFacility) value;
1007 break; 1018 break;
1008 1019
1009 case sLogLevel: 1020 case sLogLevel:
1010 intptr = (int *) &options->log_level; 1021 log_level_ptr = &options->log_level;
1011 arg = strdelim(&cp); 1022 arg = strdelim(&cp);
1012 value = log_level_number(arg); 1023 value = log_level_number(arg);
1013 if (value == SYSLOG_LEVEL_NOT_SET) 1024 if (value == SYSLOG_LEVEL_NOT_SET)
1014 fatal("%.200s line %d: unsupported log level '%s'", 1025 fatal("%.200s line %d: unsupported log level '%s'",
1015 filename, linenum, arg ? arg : "<NONE>"); 1026 filename, linenum, arg ? arg : "<NONE>");
1016 if (*intptr == -1) 1027 if (*log_level_ptr == -1)
1017 *intptr = (LogLevel) value; 1028 *log_level_ptr = (LogLevel) value;
1018 break; 1029 break;
1019 1030
1020 case sAllowTcpForwarding: 1031 case sAllowTcpForwarding:
1021 intptr = &options->allow_tcp_forwarding; 1032 intptr = &options->allow_tcp_forwarding;
1022 goto parse_flag; 1033 goto parse_flag;
1023 1034
1035 case sAllowAgentForwarding:
1036 intptr = &options->allow_agent_forwarding;
1037 goto parse_flag;
1038
1024 case sUsePrivilegeSeparation: 1039 case sUsePrivilegeSeparation:
1025 intptr = &use_privsep; 1040 intptr = &use_privsep;
1026 goto parse_flag; 1041 goto parse_flag;
@@ -1162,9 +1177,14 @@ parse_flag:
1162 intptr = &options->max_authtries; 1177 intptr = &options->max_authtries;
1163 goto parse_int; 1178 goto parse_int;
1164 1179
1180 case sMaxSessions:
1181 intptr = &options->max_sessions;
1182 goto parse_int;
1183
1165 case sBanner: 1184 case sBanner:
1166 charptr = &options->banner; 1185 charptr = &options->banner;
1167 goto parse_filename; 1186 goto parse_filename;
1187
1168 /* 1188 /*
1169 * These options can contain %X options expanded at 1189 * These options can contain %X options expanded at
1170 * connect time, so that you can specify paths like: 1190 * connect time, so that you can specify paths like:
@@ -1207,16 +1227,13 @@ parse_flag:
1207 if (!arg || *arg == '\0') 1227 if (!arg || *arg == '\0')
1208 fatal("%s line %d: Missing yes/point-to-point/" 1228 fatal("%s line %d: Missing yes/point-to-point/"
1209 "ethernet/no argument.", filename, linenum); 1229 "ethernet/no argument.", filename, linenum);
1210 value = 0; /* silence compiler */ 1230 value = -1;
1211 if (strcasecmp(arg, "ethernet") == 0) 1231 for (i = 0; tunmode_desc[i].val != -1; i++)
1212 value = SSH_TUNMODE_ETHERNET; 1232 if (strcmp(tunmode_desc[i].text, arg) == 0) {
1213 else if (strcasecmp(arg, "point-to-point") == 0) 1233 value = tunmode_desc[i].val;
1214 value = SSH_TUNMODE_POINTOPOINT; 1234 break;
1215 else if (strcasecmp(arg, "yes") == 0) 1235 }
1216 value = SSH_TUNMODE_YES; 1236 if (value == -1)
1217 else if (strcasecmp(arg, "no") == 0)
1218 value = SSH_TUNMODE_NO;
1219 else
1220 fatal("%s line %d: Bad yes/point-to-point/ethernet/" 1237 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1221 "no argument: %s", filename, linenum, arg); 1238 "no argument: %s", filename, linenum, arg);
1222 if (*intptr == -1) 1239 if (*intptr == -1)
@@ -1273,6 +1290,17 @@ parse_flag:
1273 options->adm_forced_command = xstrdup(cp + len); 1290 options->adm_forced_command = xstrdup(cp + len);
1274 return 0; 1291 return 0;
1275 1292
1293 case sChrootDirectory:
1294 charptr = &options->chroot_directory;
1295
1296 arg = strdelim(&cp);
1297 if (!arg || *arg == '\0')
1298 fatal("%s line %d: missing file name.",
1299 filename, linenum);
1300 if (*activep && *charptr == NULL)
1301 *charptr = xstrdup(arg);
1302 break;
1303
1276 case sDeprecated: 1304 case sDeprecated:
1277 logit("%s line %d: Deprecated option %s", 1305 logit("%s line %d: Deprecated option %s",
1278 filename, linenum, arg); 1306 filename, linenum, arg);
@@ -1369,17 +1397,22 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1369 M_CP_INTOPT(kerberos_authentication); 1397 M_CP_INTOPT(kerberos_authentication);
1370 M_CP_INTOPT(hostbased_authentication); 1398 M_CP_INTOPT(hostbased_authentication);
1371 M_CP_INTOPT(kbd_interactive_authentication); 1399 M_CP_INTOPT(kbd_interactive_authentication);
1400 M_CP_INTOPT(permit_root_login);
1372 1401
1373 M_CP_INTOPT(allow_tcp_forwarding); 1402 M_CP_INTOPT(allow_tcp_forwarding);
1403 M_CP_INTOPT(allow_agent_forwarding);
1374 M_CP_INTOPT(gateway_ports); 1404 M_CP_INTOPT(gateway_ports);
1375 M_CP_INTOPT(x11_display_offset); 1405 M_CP_INTOPT(x11_display_offset);
1376 M_CP_INTOPT(x11_forwarding); 1406 M_CP_INTOPT(x11_forwarding);
1377 M_CP_INTOPT(x11_use_localhost); 1407 M_CP_INTOPT(x11_use_localhost);
1408 M_CP_INTOPT(max_sessions);
1409 M_CP_INTOPT(max_authtries);
1378 1410
1379 M_CP_STROPT(banner); 1411 M_CP_STROPT(banner);
1380 if (preauth) 1412 if (preauth)
1381 return; 1413 return;
1382 M_CP_STROPT(adm_forced_command); 1414 M_CP_STROPT(adm_forced_command);
1415 M_CP_STROPT(chroot_directory);
1383} 1416}
1384 1417
1385#undef M_CP_INTOPT 1418#undef M_CP_INTOPT
@@ -1407,3 +1440,213 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1407 fatal("%s: terminating, %d bad configuration options", 1440 fatal("%s: terminating, %d bad configuration options",
1408 filename, bad_options); 1441 filename, bad_options);
1409} 1442}
1443
1444static const char *
1445fmt_intarg(ServerOpCodes code, int val)
1446{
1447 if (code == sAddressFamily) {
1448 switch (val) {
1449 case AF_INET:
1450 return "inet";
1451 case AF_INET6:
1452 return "inet6";
1453 case AF_UNSPEC:
1454 return "any";
1455 default:
1456 return "UNKNOWN";
1457 }
1458 }
1459 if (code == sPermitRootLogin) {
1460 switch (val) {
1461 case PERMIT_NO_PASSWD:
1462 return "without-passord";
1463 case PERMIT_FORCED_ONLY:
1464 return "forced-commands-only";
1465 case PERMIT_YES:
1466 return "yes";
1467 }
1468 }
1469 if (code == sProtocol) {
1470 switch (val) {
1471 case SSH_PROTO_1:
1472 return "1";
1473 case SSH_PROTO_2:
1474 return "2";
1475 case (SSH_PROTO_1|SSH_PROTO_2):
1476 return "2,1";
1477 default:
1478 return "UNKNOWN";
1479 }
1480 }
1481 if (code == sGatewayPorts && val == 2)
1482 return "clientspecified";
1483 if (code == sCompression && val == COMP_DELAYED)
1484 return "delayed";
1485 switch (val) {
1486 case -1:
1487 return "unset";
1488 case 0:
1489 return "no";
1490 case 1:
1491 return "yes";
1492 }
1493 return "UNKNOWN";
1494}
1495
1496static const char *
1497lookup_opcode_name(ServerOpCodes code)
1498{
1499 u_int i;
1500
1501 for (i = 0; keywords[i].name != NULL; i++)
1502 if (keywords[i].opcode == code)
1503 return(keywords[i].name);
1504 return "UNKNOWN";
1505}
1506
1507static void
1508dump_cfg_int(ServerOpCodes code, int val)
1509{
1510 printf("%s %d\n", lookup_opcode_name(code), val);
1511}
1512
1513static void
1514dump_cfg_fmtint(ServerOpCodes code, int val)
1515{
1516 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1517}
1518
1519static void
1520dump_cfg_string(ServerOpCodes code, const char *val)
1521{
1522 if (val == NULL)
1523 return;
1524 printf("%s %s\n", lookup_opcode_name(code), val);
1525}
1526
1527static void
1528dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1529{
1530 u_int i;
1531
1532 for (i = 0; i < count; i++)
1533 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
1534}
1535
1536void
1537dump_config(ServerOptions *o)
1538{
1539 u_int i;
1540 int ret;
1541 struct addrinfo *ai;
1542 char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1543
1544 /* these are usually at the top of the config */
1545 for (i = 0; i < o->num_ports; i++)
1546 printf("port %d\n", o->ports[i]);
1547 dump_cfg_fmtint(sProtocol, o->protocol);
1548 dump_cfg_fmtint(sAddressFamily, o->address_family);
1549
1550 /* ListenAddress must be after Port */
1551 for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1552 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1553 sizeof(addr), port, sizeof(port),
1554 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1555 error("getnameinfo failed: %.100s",
1556 (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1557 strerror(errno));
1558 } else {
1559 if (ai->ai_family == AF_INET6)
1560 printf("listenaddress [%s]:%s\n", addr, port);
1561 else
1562 printf("listenaddress %s:%s\n", addr, port);
1563 }
1564 }
1565
1566 /* integer arguments */
1567 dump_cfg_int(sServerKeyBits, o->server_key_bits);
1568 dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1569 dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1570 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1571 dump_cfg_int(sMaxAuthTries, o->max_authtries);
1572 dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1573 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1574
1575 /* formatted integer arguments */
1576 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1577 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1578 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1579 dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1580 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1581 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1582 o->hostbased_uses_name_from_packet_only);
1583 dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1584 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1585 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1586 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1587 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1588 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1589 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1590 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1591 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1592 dump_cfg_fmtint(sKbdInteractiveAuthentication,
1593 o->kbd_interactive_authentication);
1594 dump_cfg_fmtint(sChallengeResponseAuthentication,
1595 o->challenge_response_authentication);
1596 dump_cfg_fmtint(sPrintMotd, o->print_motd);
1597 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1598 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1599 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1600 dump_cfg_fmtint(sStrictModes, o->strict_modes);
1601 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1602 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1603 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1604 dump_cfg_fmtint(sUseLogin, o->use_login);
1605 dump_cfg_fmtint(sCompression, o->compression);
1606 dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1607 dump_cfg_fmtint(sUseDNS, o->use_dns);
1608 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1609 dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1610
1611 /* string arguments */
1612 dump_cfg_string(sPidFile, o->pid_file);
1613 dump_cfg_string(sXAuthLocation, o->xauth_location);
1614 dump_cfg_string(sCiphers, o->ciphers);
1615 dump_cfg_string(sMacs, o->macs);
1616 dump_cfg_string(sBanner, o->banner);
1617 dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
1618 dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
1619 dump_cfg_string(sForceCommand, o->adm_forced_command);
1620
1621 /* string arguments requiring a lookup */
1622 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1623 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1624
1625 /* string array arguments */
1626 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1627 o->host_key_files);
1628 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1629 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1630 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1631 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1632 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1633
1634 /* other arguments */
1635 for (i = 0; i < o->num_subsystems; i++)
1636 printf("subsystem %s %s\n", o->subsystem_name[i],
1637 o->subsystem_args[i]);
1638
1639 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1640 o->max_startups_rate, o->max_startups);
1641
1642 for (i = 0; tunmode_desc[i].val != -1; i++)
1643 if (tunmode_desc[i].val == o->permit_tun) {
1644 s = tunmode_desc[i].text;
1645 break;
1646 }
1647 dump_cfg_string(sPermitTunnel, s);
1648
1649 printf("permitopen");
1650 channel_print_adm_permitted_opens();
1651 printf("\n");
1652}