diff options
Diffstat (limited to 'servconf.c')
-rw-r--r-- | servconf.c | 359 |
1 files changed, 301 insertions, 58 deletions
diff --git a/servconf.c b/servconf.c index c5688912d..6760401ff 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" |
@@ -102,6 +104,7 @@ initialize_server_options(ServerOptions *options) | |||
102 | options->use_login = -1; | 104 | options->use_login = -1; |
103 | options->compression = -1; | 105 | options->compression = -1; |
104 | options->allow_tcp_forwarding = -1; | 106 | options->allow_tcp_forwarding = -1; |
107 | options->allow_agent_forwarding = -1; | ||
105 | options->num_allow_users = 0; | 108 | options->num_allow_users = 0; |
106 | options->num_deny_users = 0; | 109 | options->num_deny_users = 0; |
107 | options->num_allow_groups = 0; | 110 | options->num_allow_groups = 0; |
@@ -115,6 +118,7 @@ initialize_server_options(ServerOptions *options) | |||
115 | options->max_startups_rate = -1; | 118 | options->max_startups_rate = -1; |
116 | options->max_startups = -1; | 119 | options->max_startups = -1; |
117 | options->max_authtries = -1; | 120 | options->max_authtries = -1; |
121 | options->max_sessions = -1; | ||
118 | options->banner = NULL; | 122 | options->banner = NULL; |
119 | options->use_dns = -1; | 123 | options->use_dns = -1; |
120 | options->client_alive_interval = -1; | 124 | options->client_alive_interval = -1; |
@@ -125,6 +129,7 @@ initialize_server_options(ServerOptions *options) | |||
125 | options->permit_tun = -1; | 129 | options->permit_tun = -1; |
126 | options->num_permitted_opens = -1; | 130 | options->num_permitted_opens = -1; |
127 | options->adm_forced_command = NULL; | 131 | options->adm_forced_command = NULL; |
132 | options->chroot_directory = NULL; | ||
128 | } | 133 | } |
129 | 134 | ||
130 | void | 135 | void |
@@ -156,7 +161,7 @@ fill_default_server_options(ServerOptions *options) | |||
156 | if (options->pid_file == NULL) | 161 | if (options->pid_file == NULL) |
157 | options->pid_file = _PATH_SSH_DAEMON_PID_FILE; | 162 | options->pid_file = _PATH_SSH_DAEMON_PID_FILE; |
158 | if (options->server_key_bits == -1) | 163 | if (options->server_key_bits == -1) |
159 | options->server_key_bits = 768; | 164 | options->server_key_bits = 1024; |
160 | if (options->login_grace_time == -1) | 165 | if (options->login_grace_time == -1) |
161 | options->login_grace_time = 120; | 166 | options->login_grace_time = 120; |
162 | if (options->key_regeneration_time == -1) | 167 | if (options->key_regeneration_time == -1) |
@@ -231,6 +236,8 @@ fill_default_server_options(ServerOptions *options) | |||
231 | options->compression = COMP_DELAYED; | 236 | options->compression = COMP_DELAYED; |
232 | if (options->allow_tcp_forwarding == -1) | 237 | if (options->allow_tcp_forwarding == -1) |
233 | options->allow_tcp_forwarding = 1; | 238 | options->allow_tcp_forwarding = 1; |
239 | if (options->allow_agent_forwarding == -1) | ||
240 | options->allow_agent_forwarding = 1; | ||
234 | if (options->gateway_ports == -1) | 241 | if (options->gateway_ports == -1) |
235 | options->gateway_ports = 0; | 242 | options->gateway_ports = 0; |
236 | if (options->max_startups == -1) | 243 | if (options->max_startups == -1) |
@@ -241,6 +248,8 @@ fill_default_server_options(ServerOptions *options) | |||
241 | options->max_startups_begin = options->max_startups; | 248 | options->max_startups_begin = options->max_startups; |
242 | if (options->max_authtries == -1) | 249 | if (options->max_authtries == -1) |
243 | options->max_authtries = DEFAULT_AUTH_FAIL_MAX; | 250 | options->max_authtries = DEFAULT_AUTH_FAIL_MAX; |
251 | if (options->max_sessions == -1) | ||
252 | options->max_sessions = DEFAULT_SESSIONS_MAX; | ||
244 | if (options->use_dns == -1) | 253 | if (options->use_dns == -1) |
245 | options->use_dns = 1; | 254 | options->use_dns = 1; |
246 | if (options->client_alive_interval == -1) | 255 | if (options->client_alive_interval == -1) |
@@ -295,15 +304,15 @@ typedef enum { | |||
295 | sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, | 304 | sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, |
296 | sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, | 305 | sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, |
297 | sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, | 306 | sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, |
298 | sMaxStartups, sMaxAuthTries, | 307 | sMaxStartups, sMaxAuthTries, sMaxSessions, |
299 | sBanner, sUseDNS, sHostbasedAuthentication, | 308 | sBanner, sUseDNS, sHostbasedAuthentication, |
300 | sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, | 309 | sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, |
301 | sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, | 310 | sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, |
302 | sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, | 311 | sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, |
303 | sGssKeyEx, | 312 | sGssKeyEx, |
304 | sAcceptEnv, sPermitTunnel, | 313 | sAcceptEnv, sPermitTunnel, |
305 | sMatch, sPermitOpen, sForceCommand, | 314 | sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
306 | sUsePrivilegeSeparation, | 315 | sUsePrivilegeSeparation, sAllowAgentForwarding, |
307 | sDeprecated, sUnsupported | 316 | sDeprecated, sUnsupported |
308 | } ServerOpCodes; | 317 | } ServerOpCodes; |
309 | 318 | ||
@@ -332,7 +341,7 @@ static struct { | |||
332 | { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, | 341 | { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, |
333 | { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, | 342 | { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, |
334 | { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, | 343 | { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, |
335 | { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL }, | 344 | { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, |
336 | { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, | 345 | { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, |
337 | { "loglevel", sLogLevel, SSHCFG_GLOBAL }, | 346 | { "loglevel", sLogLevel, SSHCFG_GLOBAL }, |
338 | { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, | 347 | { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, |
@@ -398,6 +407,7 @@ static struct { | |||
398 | { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, | 407 | { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, |
399 | { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ | 408 | { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ |
400 | { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, | 409 | { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, |
410 | { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL }, | ||
401 | { "allowusers", sAllowUsers, SSHCFG_GLOBAL }, | 411 | { "allowusers", sAllowUsers, SSHCFG_GLOBAL }, |
402 | { "denyusers", sDenyUsers, SSHCFG_GLOBAL }, | 412 | { "denyusers", sDenyUsers, SSHCFG_GLOBAL }, |
403 | { "allowgroups", sAllowGroups, SSHCFG_GLOBAL }, | 413 | { "allowgroups", sAllowGroups, SSHCFG_GLOBAL }, |
@@ -408,7 +418,8 @@ static struct { | |||
408 | { "gatewayports", sGatewayPorts, SSHCFG_ALL }, | 418 | { "gatewayports", sGatewayPorts, SSHCFG_ALL }, |
409 | { "subsystem", sSubsystem, SSHCFG_GLOBAL }, | 419 | { "subsystem", sSubsystem, SSHCFG_GLOBAL }, |
410 | { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, | 420 | { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, |
411 | { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL }, | 421 | { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, |
422 | { "maxsessions", sMaxSessions, SSHCFG_ALL }, | ||
412 | { "banner", sBanner, SSHCFG_ALL }, | 423 | { "banner", sBanner, SSHCFG_ALL }, |
413 | { "usedns", sUseDNS, SSHCFG_GLOBAL }, | 424 | { "usedns", sUseDNS, SSHCFG_GLOBAL }, |
414 | { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, | 425 | { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, |
@@ -423,9 +434,21 @@ static struct { | |||
423 | { "match", sMatch, SSHCFG_ALL }, | 434 | { "match", sMatch, SSHCFG_ALL }, |
424 | { "permitopen", sPermitOpen, SSHCFG_ALL }, | 435 | { "permitopen", sPermitOpen, SSHCFG_ALL }, |
425 | { "forcecommand", sForceCommand, SSHCFG_ALL }, | 436 | { "forcecommand", sForceCommand, SSHCFG_ALL }, |
437 | { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, | ||
426 | { NULL, sBadOption, 0 } | 438 | { NULL, sBadOption, 0 } |
427 | }; | 439 | }; |
428 | 440 | ||
441 | static struct { | ||
442 | int val; | ||
443 | char *text; | ||
444 | } tunmode_desc[] = { | ||
445 | { SSH_TUNMODE_NO, "no" }, | ||
446 | { SSH_TUNMODE_POINTOPOINT, "point-to-point" }, | ||
447 | { SSH_TUNMODE_ETHERNET, "ethernet" }, | ||
448 | { SSH_TUNMODE_YES, "yes" }, | ||
449 | { -1, NULL } | ||
450 | }; | ||
451 | |||
429 | /* | 452 | /* |
430 | * Returns the number of the token pointed to by cp or sBadOption. | 453 | * Returns the number of the token pointed to by cp or sBadOption. |
431 | */ | 454 | */ |
@@ -478,7 +501,7 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port) | |||
478 | if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) | 501 | if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) |
479 | fatal("bad addr or host: %s (%s)", | 502 | fatal("bad addr or host: %s (%s)", |
480 | addr ? addr : "<NULL>", | 503 | addr ? addr : "<NULL>", |
481 | gai_strerror(gaierr)); | 504 | ssh_gai_strerror(gaierr)); |
482 | for (ai = aitop; ai->ai_next; ai = ai->ai_next) | 505 | for (ai = aitop; ai->ai_next; ai = ai->ai_next) |
483 | ; | 506 | ; |
484 | ai->ai_next = options->listen_addrs; | 507 | ai->ai_next = options->listen_addrs; |
@@ -522,24 +545,8 @@ static int | |||
522 | match_cfg_line_group(const char *grps, int line, const char *user) | 545 | match_cfg_line_group(const char *grps, int line, const char *user) |
523 | { | 546 | { |
524 | int result = 0; | 547 | int result = 0; |
525 | u_int ngrps = 0; | ||
526 | char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS]; | ||
527 | struct passwd *pw; | 548 | struct passwd *pw; |
528 | 549 | ||
529 | /* | ||
530 | * Even if we do not have a user yet, we still need to check for | ||
531 | * valid syntax. | ||
532 | */ | ||
533 | arg = cp = xstrdup(grps); | ||
534 | while ((p = strsep(&cp, ",")) != NULL && *p != '\0') { | ||
535 | if (ngrps >= MAX_MATCH_GROUPS) { | ||
536 | error("line %d: too many groups in Match Group", line); | ||
537 | result = -1; | ||
538 | goto out; | ||
539 | } | ||
540 | grplist[ngrps++] = p; | ||
541 | } | ||
542 | |||
543 | if (user == NULL) | 550 | if (user == NULL) |
544 | goto out; | 551 | goto out; |
545 | 552 | ||
@@ -549,17 +556,16 @@ match_cfg_line_group(const char *grps, int line, const char *user) | |||
549 | } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { | 556 | } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { |
550 | debug("Can't Match group because user %.100s not in any group " | 557 | debug("Can't Match group because user %.100s not in any group " |
551 | "at line %d", user, line); | 558 | "at line %d", user, line); |
552 | } else if (ga_match(grplist, ngrps) != 1) { | 559 | } else if (ga_match_pattern_list(grps) != 1) { |
553 | debug("user %.100s does not match group %.100s at line %d", | 560 | debug("user %.100s does not match group list %.100s at line %d", |
554 | user, arg, line); | 561 | user, grps, line); |
555 | } else { | 562 | } else { |
556 | debug("user %.100s matched group %.100s at line %d", user, | 563 | debug("user %.100s matched group list %.100s at line %d", user, |
557 | arg, line); | 564 | grps, line); |
558 | result = 1; | 565 | result = 1; |
559 | } | 566 | } |
560 | out: | 567 | out: |
561 | ga_free(); | 568 | ga_free(); |
562 | xfree(arg); | ||
563 | return result; | 569 | return result; |
564 | } | 570 | } |
565 | 571 | ||
@@ -612,15 +618,18 @@ match_cfg_line(char **condition, int line, const char *user, const char *host, | |||
612 | debug("connection from %.100s matched 'Host " | 618 | debug("connection from %.100s matched 'Host " |
613 | "%.100s' at line %d", host, arg, line); | 619 | "%.100s' at line %d", host, arg, line); |
614 | } else if (strcasecmp(attrib, "address") == 0) { | 620 | } else if (strcasecmp(attrib, "address") == 0) { |
615 | if (!address) { | 621 | switch (addr_match_list(address, arg)) { |
616 | result = 0; | 622 | case 1: |
617 | continue; | ||
618 | } | ||
619 | if (match_hostname(address, arg, len) != 1) | ||
620 | result = 0; | ||
621 | else | ||
622 | debug("connection from %.100s matched 'Address " | 623 | debug("connection from %.100s matched 'Address " |
623 | "%.100s' at line %d", address, arg, line); | 624 | "%.100s' at line %d", address, arg, line); |
625 | break; | ||
626 | case 0: | ||
627 | case -1: | ||
628 | result = 0; | ||
629 | break; | ||
630 | case -2: | ||
631 | return -1; | ||
632 | } | ||
624 | } else { | 633 | } else { |
625 | error("Unsupported Match attribute %s", attrib); | 634 | error("Unsupported Match attribute %s", attrib); |
626 | return -1; | 635 | return -1; |
@@ -641,6 +650,8 @@ process_server_config_line(ServerOptions *options, char *line, | |||
641 | { | 650 | { |
642 | char *cp, **charptr, *arg, *p; | 651 | char *cp, **charptr, *arg, *p; |
643 | int cmdline = 0, *intptr, value, n; | 652 | int cmdline = 0, *intptr, value, n; |
653 | SyslogFacility *log_facility_ptr; | ||
654 | LogLevel *log_level_ptr; | ||
644 | ServerOpCodes opcode; | 655 | ServerOpCodes opcode; |
645 | u_short port; | 656 | u_short port; |
646 | u_int i, flags = 0; | 657 | u_int i, flags = 0; |
@@ -706,7 +717,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
706 | 717 | ||
707 | case sServerKeyBits: | 718 | case sServerKeyBits: |
708 | intptr = &options->server_key_bits; | 719 | intptr = &options->server_key_bits; |
709 | parse_int: | 720 | parse_int: |
710 | arg = strdelim(&cp); | 721 | arg = strdelim(&cp); |
711 | if (!arg || *arg == '\0') | 722 | if (!arg || *arg == '\0') |
712 | fatal("%s line %d: missing integer value.", | 723 | fatal("%s line %d: missing integer value.", |
@@ -718,7 +729,7 @@ parse_int: | |||
718 | 729 | ||
719 | case sLoginGraceTime: | 730 | case sLoginGraceTime: |
720 | intptr = &options->login_grace_time; | 731 | intptr = &options->login_grace_time; |
721 | parse_time: | 732 | parse_time: |
722 | arg = strdelim(&cp); | 733 | arg = strdelim(&cp); |
723 | if (!arg || *arg == '\0') | 734 | if (!arg || *arg == '\0') |
724 | fatal("%s line %d: missing time value.", | 735 | fatal("%s line %d: missing time value.", |
@@ -787,7 +798,7 @@ parse_time: | |||
787 | fatal("%s line %d: too many host keys specified (max %d).", | 798 | fatal("%s line %d: too many host keys specified (max %d).", |
788 | filename, linenum, MAX_HOSTKEYS); | 799 | filename, linenum, MAX_HOSTKEYS); |
789 | charptr = &options->host_key_files[*intptr]; | 800 | charptr = &options->host_key_files[*intptr]; |
790 | parse_filename: | 801 | parse_filename: |
791 | arg = strdelim(&cp); | 802 | arg = strdelim(&cp); |
792 | if (!arg || *arg == '\0') | 803 | if (!arg || *arg == '\0') |
793 | fatal("%s line %d: missing file name.", | 804 | fatal("%s line %d: missing file name.", |
@@ -824,13 +835,13 @@ parse_filename: | |||
824 | fatal("%s line %d: Bad yes/" | 835 | fatal("%s line %d: Bad yes/" |
825 | "without-password/forced-commands-only/no " | 836 | "without-password/forced-commands-only/no " |
826 | "argument: %s", filename, linenum, arg); | 837 | "argument: %s", filename, linenum, arg); |
827 | if (*intptr == -1) | 838 | if (*activep && *intptr == -1) |
828 | *intptr = value; | 839 | *intptr = value; |
829 | break; | 840 | break; |
830 | 841 | ||
831 | case sIgnoreRhosts: | 842 | case sIgnoreRhosts: |
832 | intptr = &options->ignore_rhosts; | 843 | intptr = &options->ignore_rhosts; |
833 | parse_flag: | 844 | parse_flag: |
834 | arg = strdelim(&cp); | 845 | arg = strdelim(&cp); |
835 | if (!arg || *arg == '\0') | 846 | if (!arg || *arg == '\0') |
836 | fatal("%s line %d: missing yes/no argument.", | 847 | fatal("%s line %d: missing yes/no argument.", |
@@ -1008,31 +1019,35 @@ parse_flag: | |||
1008 | goto parse_flag; | 1019 | goto parse_flag; |
1009 | 1020 | ||
1010 | case sLogFacility: | 1021 | case sLogFacility: |
1011 | intptr = (int *) &options->log_facility; | 1022 | log_facility_ptr = &options->log_facility; |
1012 | arg = strdelim(&cp); | 1023 | arg = strdelim(&cp); |
1013 | value = log_facility_number(arg); | 1024 | value = log_facility_number(arg); |
1014 | if (value == SYSLOG_FACILITY_NOT_SET) | 1025 | if (value == SYSLOG_FACILITY_NOT_SET) |
1015 | fatal("%.200s line %d: unsupported log facility '%s'", | 1026 | fatal("%.200s line %d: unsupported log facility '%s'", |
1016 | filename, linenum, arg ? arg : "<NONE>"); | 1027 | filename, linenum, arg ? arg : "<NONE>"); |
1017 | if (*intptr == -1) | 1028 | if (*log_facility_ptr == -1) |
1018 | *intptr = (SyslogFacility) value; | 1029 | *log_facility_ptr = (SyslogFacility) value; |
1019 | break; | 1030 | break; |
1020 | 1031 | ||
1021 | case sLogLevel: | 1032 | case sLogLevel: |
1022 | intptr = (int *) &options->log_level; | 1033 | log_level_ptr = &options->log_level; |
1023 | arg = strdelim(&cp); | 1034 | arg = strdelim(&cp); |
1024 | value = log_level_number(arg); | 1035 | value = log_level_number(arg); |
1025 | if (value == SYSLOG_LEVEL_NOT_SET) | 1036 | if (value == SYSLOG_LEVEL_NOT_SET) |
1026 | fatal("%.200s line %d: unsupported log level '%s'", | 1037 | fatal("%.200s line %d: unsupported log level '%s'", |
1027 | filename, linenum, arg ? arg : "<NONE>"); | 1038 | filename, linenum, arg ? arg : "<NONE>"); |
1028 | if (*intptr == -1) | 1039 | if (*log_level_ptr == -1) |
1029 | *intptr = (LogLevel) value; | 1040 | *log_level_ptr = (LogLevel) value; |
1030 | break; | 1041 | break; |
1031 | 1042 | ||
1032 | case sAllowTcpForwarding: | 1043 | case sAllowTcpForwarding: |
1033 | intptr = &options->allow_tcp_forwarding; | 1044 | intptr = &options->allow_tcp_forwarding; |
1034 | goto parse_flag; | 1045 | goto parse_flag; |
1035 | 1046 | ||
1047 | case sAllowAgentForwarding: | ||
1048 | intptr = &options->allow_agent_forwarding; | ||
1049 | goto parse_flag; | ||
1050 | |||
1036 | case sUsePrivilegeSeparation: | 1051 | case sUsePrivilegeSeparation: |
1037 | intptr = &use_privsep; | 1052 | intptr = &use_privsep; |
1038 | goto parse_flag; | 1053 | goto parse_flag; |
@@ -1174,9 +1189,14 @@ parse_flag: | |||
1174 | intptr = &options->max_authtries; | 1189 | intptr = &options->max_authtries; |
1175 | goto parse_int; | 1190 | goto parse_int; |
1176 | 1191 | ||
1192 | case sMaxSessions: | ||
1193 | intptr = &options->max_sessions; | ||
1194 | goto parse_int; | ||
1195 | |||
1177 | case sBanner: | 1196 | case sBanner: |
1178 | charptr = &options->banner; | 1197 | charptr = &options->banner; |
1179 | goto parse_filename; | 1198 | goto parse_filename; |
1199 | |||
1180 | /* | 1200 | /* |
1181 | * These options can contain %X options expanded at | 1201 | * These options can contain %X options expanded at |
1182 | * connect time, so that you can specify paths like: | 1202 | * connect time, so that you can specify paths like: |
@@ -1219,16 +1239,13 @@ parse_flag: | |||
1219 | if (!arg || *arg == '\0') | 1239 | if (!arg || *arg == '\0') |
1220 | fatal("%s line %d: Missing yes/point-to-point/" | 1240 | fatal("%s line %d: Missing yes/point-to-point/" |
1221 | "ethernet/no argument.", filename, linenum); | 1241 | "ethernet/no argument.", filename, linenum); |
1222 | value = 0; /* silence compiler */ | 1242 | value = -1; |
1223 | if (strcasecmp(arg, "ethernet") == 0) | 1243 | for (i = 0; tunmode_desc[i].val != -1; i++) |
1224 | value = SSH_TUNMODE_ETHERNET; | 1244 | if (strcmp(tunmode_desc[i].text, arg) == 0) { |
1225 | else if (strcasecmp(arg, "point-to-point") == 0) | 1245 | value = tunmode_desc[i].val; |
1226 | value = SSH_TUNMODE_POINTOPOINT; | 1246 | break; |
1227 | else if (strcasecmp(arg, "yes") == 0) | 1247 | } |
1228 | value = SSH_TUNMODE_YES; | 1248 | if (value == -1) |
1229 | else if (strcasecmp(arg, "no") == 0) | ||
1230 | value = SSH_TUNMODE_NO; | ||
1231 | else | ||
1232 | fatal("%s line %d: Bad yes/point-to-point/ethernet/" | 1249 | fatal("%s line %d: Bad yes/point-to-point/ethernet/" |
1233 | "no argument: %s", filename, linenum, arg); | 1250 | "no argument: %s", filename, linenum, arg); |
1234 | if (*intptr == -1) | 1251 | if (*intptr == -1) |
@@ -1285,6 +1302,17 @@ parse_flag: | |||
1285 | options->adm_forced_command = xstrdup(cp + len); | 1302 | options->adm_forced_command = xstrdup(cp + len); |
1286 | return 0; | 1303 | return 0; |
1287 | 1304 | ||
1305 | case sChrootDirectory: | ||
1306 | charptr = &options->chroot_directory; | ||
1307 | |||
1308 | arg = strdelim(&cp); | ||
1309 | if (!arg || *arg == '\0') | ||
1310 | fatal("%s line %d: missing file name.", | ||
1311 | filename, linenum); | ||
1312 | if (*activep && *charptr == NULL) | ||
1313 | *charptr = xstrdup(arg); | ||
1314 | break; | ||
1315 | |||
1288 | case sDeprecated: | 1316 | case sDeprecated: |
1289 | logit("%s line %d: Deprecated option %s", | 1317 | logit("%s line %d: Deprecated option %s", |
1290 | filename, linenum, arg); | 1318 | filename, linenum, arg); |
@@ -1381,17 +1409,22 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
1381 | M_CP_INTOPT(kerberos_authentication); | 1409 | M_CP_INTOPT(kerberos_authentication); |
1382 | M_CP_INTOPT(hostbased_authentication); | 1410 | M_CP_INTOPT(hostbased_authentication); |
1383 | M_CP_INTOPT(kbd_interactive_authentication); | 1411 | M_CP_INTOPT(kbd_interactive_authentication); |
1412 | M_CP_INTOPT(permit_root_login); | ||
1384 | 1413 | ||
1385 | M_CP_INTOPT(allow_tcp_forwarding); | 1414 | M_CP_INTOPT(allow_tcp_forwarding); |
1415 | M_CP_INTOPT(allow_agent_forwarding); | ||
1386 | M_CP_INTOPT(gateway_ports); | 1416 | M_CP_INTOPT(gateway_ports); |
1387 | M_CP_INTOPT(x11_display_offset); | 1417 | M_CP_INTOPT(x11_display_offset); |
1388 | M_CP_INTOPT(x11_forwarding); | 1418 | M_CP_INTOPT(x11_forwarding); |
1389 | M_CP_INTOPT(x11_use_localhost); | 1419 | M_CP_INTOPT(x11_use_localhost); |
1420 | M_CP_INTOPT(max_sessions); | ||
1421 | M_CP_INTOPT(max_authtries); | ||
1390 | 1422 | ||
1391 | M_CP_STROPT(banner); | 1423 | M_CP_STROPT(banner); |
1392 | if (preauth) | 1424 | if (preauth) |
1393 | return; | 1425 | return; |
1394 | M_CP_STROPT(adm_forced_command); | 1426 | M_CP_STROPT(adm_forced_command); |
1427 | M_CP_STROPT(chroot_directory); | ||
1395 | } | 1428 | } |
1396 | 1429 | ||
1397 | #undef M_CP_INTOPT | 1430 | #undef M_CP_INTOPT |
@@ -1419,3 +1452,213 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, | |||
1419 | fatal("%s: terminating, %d bad configuration options", | 1452 | fatal("%s: terminating, %d bad configuration options", |
1420 | filename, bad_options); | 1453 | filename, bad_options); |
1421 | } | 1454 | } |
1455 | |||
1456 | static const char * | ||
1457 | fmt_intarg(ServerOpCodes code, int val) | ||
1458 | { | ||
1459 | if (code == sAddressFamily) { | ||
1460 | switch (val) { | ||
1461 | case AF_INET: | ||
1462 | return "inet"; | ||
1463 | case AF_INET6: | ||
1464 | return "inet6"; | ||
1465 | case AF_UNSPEC: | ||
1466 | return "any"; | ||
1467 | default: | ||
1468 | return "UNKNOWN"; | ||
1469 | } | ||
1470 | } | ||
1471 | if (code == sPermitRootLogin) { | ||
1472 | switch (val) { | ||
1473 | case PERMIT_NO_PASSWD: | ||
1474 | return "without-passord"; | ||
1475 | case PERMIT_FORCED_ONLY: | ||
1476 | return "forced-commands-only"; | ||
1477 | case PERMIT_YES: | ||
1478 | return "yes"; | ||
1479 | } | ||
1480 | } | ||
1481 | if (code == sProtocol) { | ||
1482 | switch (val) { | ||
1483 | case SSH_PROTO_1: | ||
1484 | return "1"; | ||
1485 | case SSH_PROTO_2: | ||
1486 | return "2"; | ||
1487 | case (SSH_PROTO_1|SSH_PROTO_2): | ||
1488 | return "2,1"; | ||
1489 | default: | ||
1490 | return "UNKNOWN"; | ||
1491 | } | ||
1492 | } | ||
1493 | if (code == sGatewayPorts && val == 2) | ||
1494 | return "clientspecified"; | ||
1495 | if (code == sCompression && val == COMP_DELAYED) | ||
1496 | return "delayed"; | ||
1497 | switch (val) { | ||
1498 | case -1: | ||
1499 | return "unset"; | ||
1500 | case 0: | ||
1501 | return "no"; | ||
1502 | case 1: | ||
1503 | return "yes"; | ||
1504 | } | ||
1505 | return "UNKNOWN"; | ||
1506 | } | ||
1507 | |||
1508 | static const char * | ||
1509 | lookup_opcode_name(ServerOpCodes code) | ||
1510 | { | ||
1511 | u_int i; | ||
1512 | |||
1513 | for (i = 0; keywords[i].name != NULL; i++) | ||
1514 | if (keywords[i].opcode == code) | ||
1515 | return(keywords[i].name); | ||
1516 | return "UNKNOWN"; | ||
1517 | } | ||
1518 | |||
1519 | static void | ||
1520 | dump_cfg_int(ServerOpCodes code, int val) | ||
1521 | { | ||
1522 | printf("%s %d\n", lookup_opcode_name(code), val); | ||
1523 | } | ||
1524 | |||
1525 | static void | ||
1526 | dump_cfg_fmtint(ServerOpCodes code, int val) | ||
1527 | { | ||
1528 | printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); | ||
1529 | } | ||
1530 | |||
1531 | static void | ||
1532 | dump_cfg_string(ServerOpCodes code, const char *val) | ||
1533 | { | ||
1534 | if (val == NULL) | ||
1535 | return; | ||
1536 | printf("%s %s\n", lookup_opcode_name(code), val); | ||
1537 | } | ||
1538 | |||
1539 | static void | ||
1540 | dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) | ||
1541 | { | ||
1542 | u_int i; | ||
1543 | |||
1544 | for (i = 0; i < count; i++) | ||
1545 | printf("%s %s\n", lookup_opcode_name(code), vals[i]); | ||
1546 | } | ||
1547 | |||
1548 | void | ||
1549 | dump_config(ServerOptions *o) | ||
1550 | { | ||
1551 | u_int i; | ||
1552 | int ret; | ||
1553 | struct addrinfo *ai; | ||
1554 | char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; | ||
1555 | |||
1556 | /* these are usually at the top of the config */ | ||
1557 | for (i = 0; i < o->num_ports; i++) | ||
1558 | printf("port %d\n", o->ports[i]); | ||
1559 | dump_cfg_fmtint(sProtocol, o->protocol); | ||
1560 | dump_cfg_fmtint(sAddressFamily, o->address_family); | ||
1561 | |||
1562 | /* ListenAddress must be after Port */ | ||
1563 | for (ai = o->listen_addrs; ai; ai = ai->ai_next) { | ||
1564 | if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, | ||
1565 | sizeof(addr), port, sizeof(port), | ||
1566 | NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { | ||
1567 | error("getnameinfo failed: %.100s", | ||
1568 | (ret != EAI_SYSTEM) ? gai_strerror(ret) : | ||
1569 | strerror(errno)); | ||
1570 | } else { | ||
1571 | if (ai->ai_family == AF_INET6) | ||
1572 | printf("listenaddress [%s]:%s\n", addr, port); | ||
1573 | else | ||
1574 | printf("listenaddress %s:%s\n", addr, port); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | /* integer arguments */ | ||
1579 | dump_cfg_int(sServerKeyBits, o->server_key_bits); | ||
1580 | dump_cfg_int(sLoginGraceTime, o->login_grace_time); | ||
1581 | dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); | ||
1582 | dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); | ||
1583 | dump_cfg_int(sMaxAuthTries, o->max_authtries); | ||
1584 | dump_cfg_int(sClientAliveInterval, o->client_alive_interval); | ||
1585 | dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); | ||
1586 | |||
1587 | /* formatted integer arguments */ | ||
1588 | dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); | ||
1589 | dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); | ||
1590 | dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); | ||
1591 | dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication); | ||
1592 | dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); | ||
1593 | dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, | ||
1594 | o->hostbased_uses_name_from_packet_only); | ||
1595 | dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication); | ||
1596 | dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); | ||
1597 | dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); | ||
1598 | dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); | ||
1599 | dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); | ||
1600 | dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); | ||
1601 | dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); | ||
1602 | dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); | ||
1603 | dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); | ||
1604 | dump_cfg_fmtint(sKbdInteractiveAuthentication, | ||
1605 | o->kbd_interactive_authentication); | ||
1606 | dump_cfg_fmtint(sChallengeResponseAuthentication, | ||
1607 | o->challenge_response_authentication); | ||
1608 | dump_cfg_fmtint(sPrintMotd, o->print_motd); | ||
1609 | dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); | ||
1610 | dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); | ||
1611 | dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); | ||
1612 | dump_cfg_fmtint(sStrictModes, o->strict_modes); | ||
1613 | dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); | ||
1614 | dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); | ||
1615 | dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); | ||
1616 | dump_cfg_fmtint(sUseLogin, o->use_login); | ||
1617 | dump_cfg_fmtint(sCompression, o->compression); | ||
1618 | dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); | ||
1619 | dump_cfg_fmtint(sUseDNS, o->use_dns); | ||
1620 | dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); | ||
1621 | dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); | ||
1622 | |||
1623 | /* string arguments */ | ||
1624 | dump_cfg_string(sPidFile, o->pid_file); | ||
1625 | dump_cfg_string(sXAuthLocation, o->xauth_location); | ||
1626 | dump_cfg_string(sCiphers, o->ciphers); | ||
1627 | dump_cfg_string(sMacs, o->macs); | ||
1628 | dump_cfg_string(sBanner, o->banner); | ||
1629 | dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file); | ||
1630 | dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2); | ||
1631 | dump_cfg_string(sForceCommand, o->adm_forced_command); | ||
1632 | |||
1633 | /* string arguments requiring a lookup */ | ||
1634 | dump_cfg_string(sLogLevel, log_level_name(o->log_level)); | ||
1635 | dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); | ||
1636 | |||
1637 | /* string array arguments */ | ||
1638 | dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, | ||
1639 | o->host_key_files); | ||
1640 | dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); | ||
1641 | dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); | ||
1642 | dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); | ||
1643 | dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); | ||
1644 | dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); | ||
1645 | |||
1646 | /* other arguments */ | ||
1647 | for (i = 0; i < o->num_subsystems; i++) | ||
1648 | printf("subsystem %s %s\n", o->subsystem_name[i], | ||
1649 | o->subsystem_args[i]); | ||
1650 | |||
1651 | printf("maxstartups %d:%d:%d\n", o->max_startups_begin, | ||
1652 | o->max_startups_rate, o->max_startups); | ||
1653 | |||
1654 | for (i = 0; tunmode_desc[i].val != -1; i++) | ||
1655 | if (tunmode_desc[i].val == o->permit_tun) { | ||
1656 | s = tunmode_desc[i].text; | ||
1657 | break; | ||
1658 | } | ||
1659 | dump_cfg_string(sPermitTunnel, s); | ||
1660 | |||
1661 | printf("permitopen"); | ||
1662 | channel_print_adm_permitted_opens(); | ||
1663 | printf("\n"); | ||
1664 | } | ||