1 2 /* $OpenBSD: servconf.c,v 1.229 2012/07/13 01:35:21 dtucker Exp $ */ 3 /* 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5 * All rights reserved 6 * 7 * As far as I am concerned, the code I have written for this software 8 * can be used freely for any purpose. Any derived versions of this 9 * software must be clearly marked as such, and if the derived work is 10 * incompatible with the protocol description in the RFC file, it must be 11 * called by a name other than "ssh" or "Secure Shell". 12 */ 13 14 #include <sys/types.h> 15 #include <sys/socket.h> 16 #include <sys/queue.h> 17 18 #include <netinet/in.h> 19 #include <netinet/in_systm.h> 20 #include <netinet/ip.h> 21 22 #include <netdb.h> 23 #include <pwd.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <signal.h> 28 #include <unistd.h> 29 #include <stdarg.h> 30 #include <errno.h> 31 32 #include "xmalloc.h" 33 #include "ssh.h" 34 #include "log.h" 35 #include "buffer.h" 36 #include "servconf.h" 37 #include "compat.h" 38 #include "pathnames.h" 39 #include "misc.h" 40 #include "cipher.h" 41 #include "key.h" 42 #include "kex.h" 43 #include "mac.h" 44 #include "match.h" 45 #include "channels.h" 46 #include "groupaccess.h" 47 #include "canohost.h" 48 #include "packet.h" 49 50 static void add_listen_addr(ServerOptions *, char *, int); 51 static void add_one_listen_addr(ServerOptions *, char *, int); 52 53 /* Use of privilege separation or not */ 54 extern int use_privsep; 55 extern Buffer cfg; 56 57 /* Initializes the server options to their default values. */ 58 59 void 60 initialize_server_options(ServerOptions *options) 61 { 62 memset(options, 0, sizeof(*options)); 63 options->num_ports = 0; 64 options->ports_from_cmdline = 0; 65 options->listen_addrs = NULL; 66 options->address_family = -1; 67 options->num_host_key_files = 0; 68 options->num_host_cert_files = 0; 69 options->pid_file = NULL; 70 options->server_key_bits = -1; 71 options->login_grace_time = -1; 72 options->key_regeneration_time = -1; 73 options->permit_root_login = PERMIT_NOT_SET; 74 options->ignore_rhosts = -1; 75 options->ignore_user_known_hosts = -1; 76 options->print_motd = -1; 77 options->print_lastlog = -1; 78 options->x11_forwarding = -1; 79 options->x11_display_offset = -1; 80 options->x11_use_localhost = -1; 81 options->xauth_location = NULL; 82 options->strict_modes = -1; 83 options->tcp_keep_alive = -1; 84 options->log_facility = SYSLOG_FACILITY_NOT_SET; 85 options->log_level = SYSLOG_LEVEL_NOT_SET; 86 options->rhosts_rsa_authentication = -1; 87 options->hostbased_authentication = -1; 88 options->hostbased_uses_name_from_packet_only = -1; 89 options->rsa_authentication = -1; 90 options->pubkey_authentication = -1; 91 options->kerberos_authentication = -1; 92 options->kerberos_or_local_passwd = -1; 93 options->kerberos_ticket_cleanup = -1; 94 options->kerberos_get_afs_token = -1; 95 options->gss_authentication=-1; 96 options->gss_cleanup_creds = -1; 97 options->password_authentication = -1; 98 options->kbd_interactive_authentication = -1; 99 options->challenge_response_authentication = -1; 100 options->permit_empty_passwd = -1; 101 options->permit_user_env = -1; 102 options->use_login = -1; 103 options->compression = -1; 104 options->allow_tcp_forwarding = -1; 105 options->allow_agent_forwarding = -1; 106 options->num_allow_users = 0; 107 options->num_deny_users = 0; 108 options->num_allow_groups = 0; 109 options->num_deny_groups = 0; 110 options->ciphers = NULL; 111 options->macs = NULL; 112 options->kex_algorithms = NULL; 113 options->protocol = SSH_PROTO_UNKNOWN; 114 options->gateway_ports = -1; 115 options->num_subsystems = 0; 116 options->max_startups_begin = -1; 117 options->max_startups_rate = -1; 118 options->max_startups = -1; 119 options->max_authtries = -1; 120 options->max_sessions = -1; 121 options->banner = NULL; 122 options->use_dns = -1; 123 options->client_alive_interval = -1; 124 options->client_alive_count_max = -1; 125 options->num_authkeys_files = 0; 126 options->num_accept_env = 0; 127 options->permit_tun = -1; 128 options->num_permitted_opens = -1; 129 options->adm_forced_command = NULL; 130 options->chroot_directory = NULL; 131 options->zero_knowledge_password_authentication = -1; 132 options->revoked_keys_file = NULL; 133 options->trusted_user_ca_keys = NULL; 134 options->authorized_principals_file = NULL; 135 options->ip_qos_interactive = -1; 136 options->ip_qos_bulk = -1; 137 options->version_addendum = NULL; 138 } 139 140 void 141 fill_default_server_options(ServerOptions *options) 142 { 143 if (options->protocol == SSH_PROTO_UNKNOWN) 144 options->protocol = SSH_PROTO_2; 145 if (options->num_host_key_files == 0) { 146 /* fill default hostkeys for protocols */ 147 if (options->protocol & SSH_PROTO_1) 148 options->host_key_files[options->num_host_key_files++] = 149 _PATH_HOST_KEY_FILE; 150 if (options->protocol & SSH_PROTO_2) { 151 options->host_key_files[options->num_host_key_files++] = 152 _PATH_HOST_RSA_KEY_FILE; 153 options->host_key_files[options->num_host_key_files++] = 154 _PATH_HOST_DSA_KEY_FILE; 155 options->host_key_files[options->num_host_key_files++] = 156 _PATH_HOST_ECDSA_KEY_FILE; 157 } 158 } 159 /* No certificates by default */ 160 if (options->num_ports == 0) 161 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 162 if (options->listen_addrs == NULL) 163 add_listen_addr(options, NULL, 0); 164 if (options->pid_file == NULL) 165 options->pid_file = _PATH_SSH_DAEMON_PID_FILE; 166 if (options->server_key_bits == -1) 167 options->server_key_bits = 1024; 168 if (options->login_grace_time == -1) 169 options->login_grace_time = 120; 170 if (options->key_regeneration_time == -1) 171 options->key_regeneration_time = 3600; 172 if (options->permit_root_login == PERMIT_NOT_SET) 173 options->permit_root_login = PERMIT_YES; 174 if (options->ignore_rhosts == -1) 175 options->ignore_rhosts = 1; 176 if (options->ignore_user_known_hosts == -1) 177 options->ignore_user_known_hosts = 0; 178 if (options->print_motd == -1) 179 options->print_motd = 1; 180 if (options->print_lastlog == -1) 181 options->print_lastlog = 1; 182 if (options->x11_forwarding == -1) 183 options->x11_forwarding = 0; 184 if (options->x11_display_offset == -1) 185 options->x11_display_offset = 10; 186 if (options->x11_use_localhost == -1) 187 options->x11_use_localhost = 1; 188 if (options->xauth_location == NULL) 189 options->xauth_location = _PATH_XAUTH; 190 if (options->strict_modes == -1) 191 options->strict_modes = 1; 192 if (options->tcp_keep_alive == -1) 193 options->tcp_keep_alive = 1; 194 if (options->log_facility == SYSLOG_FACILITY_NOT_SET) 195 options->log_facility = SYSLOG_FACILITY_AUTH; 196 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 197 options->log_level = SYSLOG_LEVEL_INFO; 198 if (options->rhosts_rsa_authentication == -1) 199 options->rhosts_rsa_authentication = 0; 200 if (options->hostbased_authentication == -1) 201 options->hostbased_authentication = 0; 202 if (options->hostbased_uses_name_from_packet_only == -1) 203 options->hostbased_uses_name_from_packet_only = 0; 204 if (options->rsa_authentication == -1) 205 options->rsa_authentication = 1; 206 if (options->pubkey_authentication == -1) 207 options->pubkey_authentication = 1; 208 if (options->kerberos_authentication == -1) 209 options->kerberos_authentication = 0; 210 if (options->kerberos_or_local_passwd == -1) 211 options->kerberos_or_local_passwd = 1; 212 if (options->kerberos_ticket_cleanup == -1) 213 options->kerberos_ticket_cleanup = 1; 214 if (options->kerberos_get_afs_token == -1) 215 options->kerberos_get_afs_token = 0; 216 if (options->gss_authentication == -1) 217 options->gss_authentication = 0; 218 if (options->gss_cleanup_creds == -1) 219 options->gss_cleanup_creds = 1; 220 if (options->password_authentication == -1) 221 options->password_authentication = 1; 222 if (options->kbd_interactive_authentication == -1) 223 options->kbd_interactive_authentication = 0; 224 if (options->challenge_response_authentication == -1) 225 options->challenge_response_authentication = 1; 226 if (options->permit_empty_passwd == -1) 227 options->permit_empty_passwd = 0; 228 if (options->permit_user_env == -1) 229 options->permit_user_env = 0; 230 if (options->use_login == -1) 231 options->use_login = 0; 232 if (options->compression == -1) 233 options->compression = COMP_DELAYED; 234 if (options->allow_tcp_forwarding == -1) 235 options->allow_tcp_forwarding = 1; 236 if (options->allow_agent_forwarding == -1) 237 options->allow_agent_forwarding = 1; 238 if (options->gateway_ports == -1) 239 options->gateway_ports = 0; 240 if (options->max_startups == -1) 241 options->max_startups = 10; 242 if (options->max_startups_rate == -1) 243 options->max_startups_rate = 100; /* 100% */ 244 if (options->max_startups_begin == -1) 245 options->max_startups_begin = options->max_startups; 246 if (options->max_authtries == -1) 247 options->max_authtries = DEFAULT_AUTH_FAIL_MAX; 248 if (options->max_sessions == -1) 249 options->max_sessions = DEFAULT_SESSIONS_MAX; 250 if (options->use_dns == -1) 251 options->use_dns = 1; 252 if (options->client_alive_interval == -1) 253 options->client_alive_interval = 0; 254 if (options->client_alive_count_max == -1) 255 options->client_alive_count_max = 3; 256 if (options->num_authkeys_files == 0) { 257 options->authorized_keys_files[options->num_authkeys_files++] = 258 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); 259 options->authorized_keys_files[options->num_authkeys_files++] = 260 xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); 261 } 262 if (options->permit_tun == -1) 263 options->permit_tun = SSH_TUNMODE_NO; 264 if (options->zero_knowledge_password_authentication == -1) 265 options->zero_knowledge_password_authentication = 0; 266 if (options->ip_qos_interactive == -1) 267 options->ip_qos_interactive = IPTOS_LOWDELAY; 268 if (options->ip_qos_bulk == -1) 269 options->ip_qos_bulk = IPTOS_THROUGHPUT; 270 if (options->version_addendum == NULL) 271 options->version_addendum = xstrdup(""); 272 /* Turn privilege separation on by default */ 273 if (use_privsep == -1) 274 use_privsep = PRIVSEP_NOSANDBOX; 275 } 276 277 /* Keyword tokens. */ 278 typedef enum { 279 sBadOption, /* == unknown option */ 280 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, 281 sPermitRootLogin, sLogFacility, sLogLevel, 282 sRhostsRSAAuthentication, sRSAAuthentication, 283 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 284 sKerberosGetAFSToken, 285 sKerberosTgtPassing, sChallengeResponseAuthentication, 286 sPasswordAuthentication, sKbdInteractiveAuthentication, 287 sListenAddress, sAddressFamily, 288 sPrintMotd, sPrintLastLog, sIgnoreRhosts, 289 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, 290 sStrictModes, sEmptyPasswd, sTCPKeepAlive, 291 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, 292 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 293 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 294 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, 295 sMaxStartups, sMaxAuthTries, sMaxSessions, 296 sBanner, sUseDNS, sHostbasedAuthentication, 297 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 298 sClientAliveCountMax, sAuthorizedKeysFile, 299 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, 300 sMatch, sPermitOpen, sForceCommand, sChrootDirectory, 301 sUsePrivilegeSeparation, sAllowAgentForwarding, 302 sZeroKnowledgePasswordAuthentication, sHostCertificate, 303 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, 304 sKexAlgorithms, sIPQoS, sVersionAddendum, 305 sDeprecated, sUnsupported 306 } ServerOpCodes; 307 308 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ 309 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ 310 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) 311 312 /* Textual representation of the tokens. */ 313 static struct { 314 const char *name; 315 ServerOpCodes opcode; 316 u_int flags; 317 } keywords[] = { 318 { "port", sPort, SSHCFG_GLOBAL }, 319 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, 320 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ 321 { "pidfile", sPidFile, SSHCFG_GLOBAL }, 322 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, 323 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, 324 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, 325 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, 326 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, 327 { "loglevel", sLogLevel, SSHCFG_GLOBAL }, 328 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, 329 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL }, 330 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, 331 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL }, 332 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL }, 333 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, 334 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ 335 #ifdef KRB5 336 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, 337 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL }, 338 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL }, 339 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL }, 340 #else 341 { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, 342 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, 343 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, 344 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, 345 #endif 346 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, 347 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, 348 #ifdef GSSAPI 349 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, 350 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, 351 #else 352 { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, 353 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, 354 #endif 355 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, 356 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, 357 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, 358 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ 359 #ifdef JPAKE 360 { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL }, 361 #else 362 { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL }, 363 #endif 364 { "checkmail", sDeprecated, SSHCFG_GLOBAL }, 365 { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, 366 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, 367 { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, 368 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL }, 369 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL }, 370 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, 371 { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, 372 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, 373 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, 374 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, 375 { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, 376 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, 377 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, 378 { "uselogin", sUseLogin, SSHCFG_GLOBAL }, 379 { "compression", sCompression, SSHCFG_GLOBAL }, 380 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, 381 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ 382 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, 383 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL }, 384 { "allowusers", sAllowUsers, SSHCFG_ALL }, 385 { "denyusers", sDenyUsers, SSHCFG_ALL }, 386 { "allowgroups", sAllowGroups, SSHCFG_ALL }, 387 { "denygroups", sDenyGroups, SSHCFG_ALL }, 388 { "ciphers", sCiphers, SSHCFG_GLOBAL }, 389 { "macs", sMacs, SSHCFG_GLOBAL }, 390 { "protocol", sProtocol, SSHCFG_GLOBAL }, 391 { "gatewayports", sGatewayPorts, SSHCFG_ALL }, 392 { "subsystem", sSubsystem, SSHCFG_GLOBAL }, 393 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, 394 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, 395 { "maxsessions", sMaxSessions, SSHCFG_ALL }, 396 { "banner", sBanner, SSHCFG_ALL }, 397 { "usedns", sUseDNS, SSHCFG_GLOBAL }, 398 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, 399 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, 400 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL }, 401 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, 402 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, 403 { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, 404 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL}, 405 { "acceptenv", sAcceptEnv, SSHCFG_ALL }, 406 { "permittunnel", sPermitTunnel, SSHCFG_ALL }, 407 { "match", sMatch, SSHCFG_ALL }, 408 { "permitopen", sPermitOpen, SSHCFG_ALL }, 409 { "forcecommand", sForceCommand, SSHCFG_ALL }, 410 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, 411 { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, 412 { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, 413 { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, 414 { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, 415 { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, 416 { "ipqos", sIPQoS, SSHCFG_ALL }, 417 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, 418 { NULL, sBadOption, 0 } 419 }; 420 421 static struct { 422 int val; 423 char *text; 424 } tunmode_desc[] = { 425 { SSH_TUNMODE_NO, "no" }, 426 { SSH_TUNMODE_POINTOPOINT, "point-to-point" }, 427 { SSH_TUNMODE_ETHERNET, "ethernet" }, 428 { SSH_TUNMODE_YES, "yes" }, 429 { -1, NULL } 430 }; 431 432 /* 433 * Returns the number of the token pointed to by cp or sBadOption. 434 */ 435 436 static ServerOpCodes 437 parse_token(const char *cp, const char *filename, 438 int linenum, u_int *flags) 439 { 440 u_int i; 441 442 for (i = 0; keywords[i].name; i++) 443 if (strcasecmp(cp, keywords[i].name) == 0) { 444 *flags = keywords[i].flags; 445 return keywords[i].opcode; 446 } 447 448 error("%s: line %d: Bad configuration option: %s", 449 filename, linenum, cp); 450 return sBadOption; 451 } 452 453 char * 454 derelativise_path(const char *path) 455 { 456 char *expanded, *ret, cwd[MAXPATHLEN]; 457 458 expanded = tilde_expand_filename(path, getuid()); 459 if (*expanded == '/') 460 return expanded; 461 if (getcwd(cwd, sizeof(cwd)) == NULL) 462 fatal("%s: getcwd: %s", __func__, strerror(errno)); 463 xasprintf(&ret, "%s/%s", cwd, expanded); 464 xfree(expanded); 465 return ret; 466 } 467 468 static void 469 add_listen_addr(ServerOptions *options, char *addr, int port) 470 { 471 u_int i; 472 473 if (options->num_ports == 0) 474 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 475 if (options->address_family == -1) 476 options->address_family = AF_UNSPEC; 477 if (port == 0) 478 for (i = 0; i < options->num_ports; i++) 479 add_one_listen_addr(options, addr, options->ports[i]); 480 else 481 add_one_listen_addr(options, addr, port); 482 } 483 484 static void 485 add_one_listen_addr(ServerOptions *options, char *addr, int port) 486 { 487 struct addrinfo hints, *ai, *aitop; 488 char strport[NI_MAXSERV]; 489 int gaierr; 490 491 memset(&hints, 0, sizeof(hints)); 492 hints.ai_family = options->address_family; 493 hints.ai_socktype = SOCK_STREAM; 494 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 495 snprintf(strport, sizeof strport, "%d", port); 496 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 497 fatal("bad addr or host: %s (%s)", 498 addr ? addr : "<NULL>", 499 ssh_gai_strerror(gaierr)); 500 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 501 ; 502 ai->ai_next = options->listen_addrs; 503 options->listen_addrs = aitop; 504 } 505 506 struct connection_info * 507 get_connection_info(int populate, int use_dns) 508 { 509 static struct connection_info ci; 510 511 if (!populate) 512 return &ci; 513 ci.host = get_canonical_hostname(use_dns); 514 ci.address = get_remote_ipaddr(); 515 ci.laddress = get_local_ipaddr(packet_get_connection_in()); 516 ci.lport = get_local_port(); 517 return &ci; 518 } 519 520 /* 521 * The strategy for the Match blocks is that the config file is parsed twice. 522 * 523 * The first time is at startup. activep is initialized to 1 and the 524 * directives in the global context are processed and acted on. Hitting a 525 * Match directive unsets activep and the directives inside the block are 526 * checked for syntax only. 527 * 528 * The second time is after a connection has been established but before 529 * authentication. activep is initialized to 2 and global config directives 530 * are ignored since they have already been processed. If the criteria in a 531 * Match block is met, activep is set and the subsequent directives 532 * processed and actioned until EOF or another Match block unsets it. Any 533 * options set are copied into the main server config. 534 * 535 * Potential additions/improvements: 536 * - Add Match support for pre-kex directives, eg Protocol, Ciphers. 537 * 538 * - Add a Tag directive (idea from David Leonard) ala pf, eg: 539 * Match Address 192.168.0.* 540 * Tag trusted 541 * Match Group wheel 542 * Tag trusted 543 * Match Tag trusted 544 * AllowTcpForwarding yes 545 * GatewayPorts clientspecified 546 * [...] 547 * 548 * - Add a PermittedChannelRequests directive 549 * Match Group shell 550 * PermittedChannelRequests session,forwarded-tcpip 551 */ 552 553 static int 554 match_cfg_line_group(const char *grps, int line, const char *user) 555 { 556 int result = 0; 557 struct passwd *pw; 558 559 if (user == NULL) 560 goto out; 561 562 if ((pw = getpwnam(user)) == NULL) { 563 debug("Can't match group at line %d because user %.100s does " 564 "not exist", line, user); 565 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 566 debug("Can't Match group because user %.100s not in any group " 567 "at line %d", user, line); 568 } else if (ga_match_pattern_list(grps) != 1) { 569 debug("user %.100s does not match group list %.100s at line %d", 570 user, grps, line); 571 } else { 572 debug("user %.100s matched group list %.100s at line %d", user, 573 grps, line); 574 result = 1; 575 } 576 out: 577 ga_free(); 578 return result; 579 } 580 581 /* 582 * All of the attributes on a single Match line are ANDed together, so we need to check every 583 * attribute and set the result to zero if any attribute does not match. 584 */ 585 static int 586 match_cfg_line(char **condition, int line, struct connection_info *ci) 587 { 588 int result = 1, port; 589 char *arg, *attrib, *cp = *condition; 590 size_t len; 591 592 if (ci == NULL) 593 debug3("checking syntax for 'Match %s'", cp); 594 else 595 debug3("checking match for '%s' user %s host %s addr %s " 596 "laddr %s lport %d", cp, ci->user ? ci->user : "(null)", 597 ci->host ? ci->host : "(null)", 598 ci->address ? ci->address : "(null)", 599 ci->laddress ? ci->laddress : "(null)", ci->lport); 600 601 while ((attrib = strdelim(&cp)) && *attrib != '\0') { 602 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 603 error("Missing Match criteria for %s", attrib); 604 return -1; 605 } 606 len = strlen(arg); 607 if (strcasecmp(attrib, "user") == 0) { 608 if (ci == NULL || ci->user == NULL) { 609 result = 0; 610 continue; 611 } 612 if (match_pattern_list(ci->user, arg, len, 0) != 1) 613 result = 0; 614 else 615 debug("user %.100s matched 'User %.100s' at " 616 "line %d", ci->user, arg, line); 617 } else if (strcasecmp(attrib, "group") == 0) { 618 if (ci == NULL || ci->user == NULL) { 619 result = 0; 620 continue; 621 } 622 switch (match_cfg_line_group(arg, line, ci->user)) { 623 case -1: 624 return -1; 625 case 0: 626 result = 0; 627 } 628 } else if (strcasecmp(attrib, "host") == 0) { 629 if (ci == NULL || ci->host == NULL) { 630 result = 0; 631 continue; 632 } 633 if (match_hostname(ci->host, arg, len) != 1) 634 result = 0; 635 else 636 debug("connection from %.100s matched 'Host " 637 "%.100s' at line %d", ci->host, arg, line); 638 } else if (strcasecmp(attrib, "address") == 0) { 639 if (ci == NULL || ci->address == NULL) { 640 result = 0; 641 continue; 642 } 643 switch (addr_match_list(ci->address, arg)) { 644 case 1: 645 debug("connection from %.100s matched 'Address " 646 "%.100s' at line %d", ci->address, arg, line); 647 break; 648 case 0: 649 case -1: 650 result = 0; 651 break; 652 case -2: 653 return -1; 654 } 655 } else if (strcasecmp(attrib, "localaddress") == 0){ 656 if (ci == NULL || ci->laddress == NULL) { 657 result = 0; 658 continue; 659 } 660 switch (addr_match_list(ci->laddress, arg)) { 661 case 1: 662 debug("connection from %.100s matched " 663 "'LocalAddress %.100s' at line %d", 664 ci->laddress, arg, line); 665 break; 666 case 0: 667 case -1: 668 result = 0; 669 break; 670 case -2: 671 return -1; 672 } 673 } else if (strcasecmp(attrib, "localport") == 0) { 674 if ((port = a2port(arg)) == -1) { 675 error("Invalid LocalPort '%s' on Match line", 676 arg); 677 return -1; 678 } 679 if (ci == NULL || ci->lport == 0) { 680 result = 0; 681 continue; 682 } 683 /* TODO support port lists */ 684 if (port == ci->lport) 685 debug("connection from %.100s matched " 686 "'LocalPort %d' at line %d", 687 ci->laddress, port, line); 688 else 689 result = 0; 690 } else { 691 error("Unsupported Match attribute %s", attrib); 692 return -1; 693 } 694 } 695 if (ci != NULL) 696 debug3("match %sfound", result ? "" : "not "); 697 *condition = cp; 698 return result; 699 } 700 701 #define WHITESPACE " \t\r\n" 702 703 /* Multistate option parsing */ 704 struct multistate { 705 char *key; 706 int value; 707 }; 708 static const struct multistate multistate_addressfamily[] = { 709 { "inet", AF_INET }, 710 { "inet6", AF_INET6 }, 711 { "any", AF_UNSPEC }, 712 { NULL, -1 } 713 }; 714 static const struct multistate multistate_permitrootlogin[] = { 715 { "without-password", PERMIT_NO_PASSWD }, 716 { "forced-commands-only", PERMIT_FORCED_ONLY }, 717 { "yes", PERMIT_YES }, 718 { "no", PERMIT_NO }, 719 { NULL, -1 } 720 }; 721 static const struct multistate multistate_compression[] = { 722 { "delayed", COMP_DELAYED }, 723 { "yes", COMP_ZLIB }, 724 { "no", COMP_NONE }, 725 { NULL, -1 } 726 }; 727 static const struct multistate multistate_gatewayports[] = { 728 { "clientspecified", 2 }, 729 { "yes", 1 }, 730 { "no", 0 }, 731 { NULL, -1 } 732 }; 733 static const struct multistate multistate_privsep[] = { 734 { "yes", PRIVSEP_NOSANDBOX }, 735 { "sandbox", PRIVSEP_ON }, 736 { "nosandbox", PRIVSEP_NOSANDBOX }, 737 { "no", PRIVSEP_OFF }, 738 { NULL, -1 } 739 }; 740 741 int 742 process_server_config_line(ServerOptions *options, char *line, 743 const char *filename, int linenum, int *activep, 744 struct connection_info *connectinfo) 745 { 746 char *cp, **charptr, *arg, *p; 747 int cmdline = 0, *intptr, value, value2, n; 748 SyslogFacility *log_facility_ptr; 749 LogLevel *log_level_ptr; 750 ServerOpCodes opcode; 751 int port; 752 u_int i, flags = 0; 753 size_t len; 754 const struct multistate *multistate_ptr; 755 756 cp = line; 757 if ((arg = strdelim(&cp)) == NULL) 758 return 0; 759 /* Ignore leading whitespace */ 760 if (*arg == '\0') 761 arg = strdelim(&cp); 762 if (!arg || !*arg || *arg == '#') 763 return 0; 764 intptr = NULL; 765 charptr = NULL; 766 opcode = parse_token(arg, filename, linenum, &flags); 767 768 if (activep == NULL) { /* We are processing a command line directive */ 769 cmdline = 1; 770 activep = &cmdline; 771 } 772 if (*activep && opcode != sMatch) 773 debug3("%s:%d setting %s %s", filename, linenum, arg, cp); 774 if (*activep == 0 && !(flags & SSHCFG_MATCH)) { 775 if (connectinfo == NULL) { 776 fatal("%s line %d: Directive '%s' is not allowed " 777 "within a Match block", filename, linenum, arg); 778 } else { /* this is a directive we have already processed */ 779 while (arg) 780 arg = strdelim(&cp); 781 return 0; 782 } 783 } 784 785 switch (opcode) { 786 case sBadOption: 787 return -1; 788 case sPort: 789 /* ignore ports from configfile if cmdline specifies ports */ 790 if (options->ports_from_cmdline) 791 return 0; 792 if (options->listen_addrs != NULL) 793 fatal("%s line %d: ports must be specified before " 794 "ListenAddress.", filename, linenum); 795 if (options->num_ports >= MAX_PORTS) 796 fatal("%s line %d: too many ports.", 797 filename, linenum); 798 arg = strdelim(&cp); 799 if (!arg || *arg == '\0') 800 fatal("%s line %d: missing port number.", 801 filename, linenum); 802 options->ports[options->num_ports++] = a2port(arg); 803 if (options->ports[options->num_ports-1] <= 0) 804 fatal("%s line %d: Badly formatted port number.", 805 filename, linenum); 806 break; 807 808 case sServerKeyBits: 809 intptr = &options->server_key_bits; 810 parse_int: 811 arg = strdelim(&cp); 812 if (!arg || *arg == '\0') 813 fatal("%s line %d: missing integer value.", 814 filename, linenum); 815 value = atoi(arg); 816 if (*activep && *intptr == -1) 817 *intptr = value; 818 break; 819 820 case sLoginGraceTime: 821 intptr = &options->login_grace_time; 822 parse_time: 823 arg = strdelim(&cp); 824 if (!arg || *arg == '\0') 825 fatal("%s line %d: missing time value.", 826 filename, linenum); 827 if ((value = convtime(arg)) == -1) 828 fatal("%s line %d: invalid time value.", 829 filename, linenum); 830 if (*intptr == -1) 831 *intptr = value; 832 break; 833 834 case sKeyRegenerationTime: 835 intptr = &options->key_regeneration_time; 836 goto parse_time; 837 838 case sListenAddress: 839 arg = strdelim(&cp); 840 if (arg == NULL || *arg == '\0') 841 fatal("%s line %d: missing address", 842 filename, linenum); 843 /* check for bare IPv6 address: no "[]" and 2 or more ":" */ 844 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL 845 && strchr(p+1, ':') != NULL) { 846 add_listen_addr(options, arg, 0); 847 break; 848 } 849 p = hpdelim(&arg); 850 if (p == NULL) 851 fatal("%s line %d: bad address:port usage", 852 filename, linenum); 853 p = cleanhostname(p); 854 if (arg == NULL) 855 port = 0; 856 else if ((port = a2port(arg)) <= 0) 857 fatal("%s line %d: bad port number", filename, linenum); 858 859 add_listen_addr(options, p, port); 860 861 break; 862 863 case sAddressFamily: 864 intptr = &options->address_family; 865 multistate_ptr = multistate_addressfamily; 866 if (options->listen_addrs != NULL) 867 fatal("%s line %d: address family must be specified " 868 "before ListenAddress.", filename, linenum); 869 parse_multistate: 870 arg = strdelim(&cp); 871 if (!arg || *arg == '\0') 872 fatal("%s line %d: missing argument.", 873 filename, linenum); 874 value = -1; 875 for (i = 0; multistate_ptr[i].key != NULL; i++) { 876 if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 877 value = multistate_ptr[i].value; 878 break; 879 } 880 } 881 if (value == -1) 882 fatal("%s line %d: unsupported option \"%s\".", 883 filename, linenum, arg); 884 if (*activep && *intptr == -1) 885 *intptr = value; 886 break; 887 888 case sHostKeyFile: 889 intptr = &options->num_host_key_files; 890 if (*intptr >= MAX_HOSTKEYS) 891 fatal("%s line %d: too many host keys specified (max %d).", 892 filename, linenum, MAX_HOSTKEYS); 893 charptr = &options->host_key_files[*intptr]; 894 parse_filename: 895 arg = strdelim(&cp); 896 if (!arg || *arg == '\0') 897 fatal("%s line %d: missing file name.", 898 filename, linenum); 899 if (*activep && *charptr == NULL) { 900 *charptr = derelativise_path(arg); 901 /* increase optional counter */ 902 if (intptr != NULL) 903 *intptr = *intptr + 1; 904 } 905 break; 906 907 case sHostCertificate: 908 intptr = &options->num_host_cert_files; 909 if (*intptr >= MAX_HOSTKEYS) 910 fatal("%s line %d: too many host certificates " 911 "specified (max %d).", filename, linenum, 912 MAX_HOSTCERTS); 913 charptr = &options->host_cert_files[*intptr]; 914 goto parse_filename; 915 break; 916 917 case sPidFile: 918 charptr = &options->pid_file; 919 goto parse_filename; 920 921 case sPermitRootLogin: 922 intptr = &options->permit_root_login; 923 multistate_ptr = multistate_permitrootlogin; 924 goto parse_multistate; 925 926 case sIgnoreRhosts: 927 intptr = &options->ignore_rhosts; 928 parse_flag: 929 arg = strdelim(&cp); 930 if (!arg || *arg == '\0') 931 fatal("%s line %d: missing yes/no argument.", 932 filename, linenum); 933 value = 0; /* silence compiler */ 934 if (strcmp(arg, "yes") == 0) 935 value = 1; 936 else if (strcmp(arg, "no") == 0) 937 value = 0; 938 else 939 fatal("%s line %d: Bad yes/no argument: %s", 940 filename, linenum, arg); 941 if (*activep && *intptr == -1) 942 *intptr = value; 943 break; 944 945 case sIgnoreUserKnownHosts: 946 intptr = &options->ignore_user_known_hosts; 947 goto parse_flag; 948 949 case sRhostsRSAAuthentication: 950 intptr = &options->rhosts_rsa_authentication; 951 goto parse_flag; 952 953 case sHostbasedAuthentication: 954 intptr = &options->hostbased_authentication; 955 goto parse_flag; 956 957 case sHostbasedUsesNameFromPacketOnly: 958 intptr = &options->hostbased_uses_name_from_packet_only; 959 goto parse_flag; 960 961 case sRSAAuthentication: 962 intptr = &options->rsa_authentication; 963 goto parse_flag; 964 965 case sPubkeyAuthentication: 966 intptr = &options->pubkey_authentication; 967 goto parse_flag; 968 969 case sKerberosAuthentication: 970 intptr = &options->kerberos_authentication; 971 goto parse_flag; 972 973 case sKerberosOrLocalPasswd: 974 intptr = &options->kerberos_or_local_passwd; 975 goto parse_flag; 976 977 case sKerberosTicketCleanup: 978 intptr = &options->kerberos_ticket_cleanup; 979 goto parse_flag; 980 981 case sKerberosGetAFSToken: 982 intptr = &options->kerberos_get_afs_token; 983 goto parse_flag; 984 985 case sGssAuthentication: 986 intptr = &options->gss_authentication; 987 goto parse_flag; 988 989 case sGssCleanupCreds: 990 intptr = &options->gss_cleanup_creds; 991 goto parse_flag; 992 993 case sPasswordAuthentication: 994 intptr = &options->password_authentication; 995 goto parse_flag; 996 997 case sZeroKnowledgePasswordAuthentication: 998 intptr = &options->zero_knowledge_password_authentication; 999 goto parse_flag; 1000 1001 case sKbdInteractiveAuthentication: 1002 intptr = &options->kbd_interactive_authentication; 1003 goto parse_flag; 1004 1005 case sChallengeResponseAuthentication: 1006 intptr = &options->challenge_response_authentication; 1007 goto parse_flag; 1008 1009 case sPrintMotd: 1010 intptr = &options->print_motd; 1011 goto parse_flag; 1012 1013 case sPrintLastLog: 1014 intptr = &options->print_lastlog; 1015 goto parse_flag; 1016 1017 case sX11Forwarding: 1018 intptr = &options->x11_forwarding; 1019 goto parse_flag; 1020 1021 case sX11DisplayOffset: 1022 intptr = &options->x11_display_offset; 1023 goto parse_int; 1024 1025 case sX11UseLocalhost: 1026 intptr = &options->x11_use_localhost; 1027 goto parse_flag; 1028 1029 case sXAuthLocation: 1030 charptr = &options->xauth_location; 1031 goto parse_filename; 1032 1033 case sStrictModes: 1034 intptr = &options->strict_modes; 1035 goto parse_flag; 1036 1037 case sTCPKeepAlive: 1038 intptr = &options->tcp_keep_alive; 1039 goto parse_flag; 1040 1041 case sEmptyPasswd: 1042 intptr = &options->permit_empty_passwd; 1043 goto parse_flag; 1044 1045 case sPermitUserEnvironment: 1046 intptr = &options->permit_user_env; 1047 goto parse_flag; 1048 1049 case sUseLogin: 1050 intptr = &options->use_login; 1051 goto parse_flag; 1052 1053 case sCompression: 1054 intptr = &options->compression; 1055 multistate_ptr = multistate_compression; 1056 goto parse_multistate; 1057 1058 case sGatewayPorts: 1059 intptr = &options->gateway_ports; 1060 multistate_ptr = multistate_gatewayports; 1061 goto parse_multistate; 1062 1063 case sUseDNS: 1064 intptr = &options->use_dns; 1065 goto parse_flag; 1066 1067 case sLogFacility: 1068 log_facility_ptr = &options->log_facility; 1069 arg = strdelim(&cp); 1070 value = log_facility_number(arg); 1071 if (value == SYSLOG_FACILITY_NOT_SET) 1072 fatal("%.200s line %d: unsupported log facility '%s'", 1073 filename, linenum, arg ? arg : "<NONE>"); 1074 if (*log_facility_ptr == -1) 1075 *log_facility_ptr = (SyslogFacility) value; 1076 break; 1077 1078 case sLogLevel: 1079 log_level_ptr = &options->log_level; 1080 arg = strdelim(&cp); 1081 value = log_level_number(arg); 1082 if (value == SYSLOG_LEVEL_NOT_SET) 1083 fatal("%.200s line %d: unsupported log level '%s'", 1084 filename, linenum, arg ? arg : "<NONE>"); 1085 if (*log_level_ptr == -1) 1086 *log_level_ptr = (LogLevel) value; 1087 break; 1088 1089 case sAllowTcpForwarding: 1090 intptr = &options->allow_tcp_forwarding; 1091 goto parse_flag; 1092 1093 case sAllowAgentForwarding: 1094 intptr = &options->allow_agent_forwarding; 1095 goto parse_flag; 1096 1097 case sUsePrivilegeSeparation: 1098 intptr = &use_privsep; 1099 multistate_ptr = multistate_privsep; 1100 goto parse_multistate; 1101 1102 case sAllowUsers: 1103 while ((arg = strdelim(&cp)) && *arg != '\0') { 1104 if (options->num_allow_users >= MAX_ALLOW_USERS) 1105 fatal("%s line %d: too many allow users.", 1106 filename, linenum); 1107 if (!*activep) 1108 continue; 1109 options->allow_users[options->num_allow_users++] = 1110 xstrdup(arg); 1111 } 1112 break; 1113 1114 case sDenyUsers: 1115 while ((arg = strdelim(&cp)) && *arg != '\0') { 1116 if (options->num_deny_users >= MAX_DENY_USERS) 1117 fatal("%s line %d: too many deny users.", 1118 filename, linenum); 1119 if (!*activep) 1120 continue; 1121 options->deny_users[options->num_deny_users++] = 1122 xstrdup(arg); 1123 } 1124 break; 1125 1126 case sAllowGroups: 1127 while ((arg = strdelim(&cp)) && *arg != '\0') { 1128 if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 1129 fatal("%s line %d: too many allow groups.", 1130 filename, linenum); 1131 if (!*activep) 1132 continue; 1133 options->allow_groups[options->num_allow_groups++] = 1134 xstrdup(arg); 1135 } 1136 break; 1137 1138 case sDenyGroups: 1139 while ((arg = strdelim(&cp)) && *arg != '\0') { 1140 if (options->num_deny_groups >= MAX_DENY_GROUPS) 1141 fatal("%s line %d: too many deny groups.", 1142 filename, linenum); 1143 if (!*activep) 1144 continue; 1145 options->deny_groups[options->num_deny_groups++] = 1146 xstrdup(arg); 1147 } 1148 break; 1149 1150 case sCiphers: 1151 arg = strdelim(&cp); 1152 if (!arg || *arg == '\0') 1153 fatal("%s line %d: Missing argument.", filename, linenum); 1154 if (!ciphers_valid(arg)) 1155 fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 1156 filename, linenum, arg ? arg : "<NONE>"); 1157 if (options->ciphers == NULL) 1158 options->ciphers = xstrdup(arg); 1159 break; 1160 1161 case sMacs: 1162 arg = strdelim(&cp); 1163 if (!arg || *arg == '\0') 1164 fatal("%s line %d: Missing argument.", filename, linenum); 1165 if (!mac_valid(arg)) 1166 fatal("%s line %d: Bad SSH2 mac spec '%s'.", 1167 filename, linenum, arg ? arg : "<NONE>"); 1168 if (options->macs == NULL) 1169 options->macs = xstrdup(arg); 1170 break; 1171 1172 case sKexAlgorithms: 1173 arg = strdelim(&cp); 1174 if (!arg || *arg == '\0') 1175 fatal("%s line %d: Missing argument.", 1176 filename, linenum); 1177 if (!kex_names_valid(arg)) 1178 fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", 1179 filename, linenum, arg ? arg : "<NONE>"); 1180 if (options->kex_algorithms == NULL) 1181 options->kex_algorithms = xstrdup(arg); 1182 break; 1183 1184 case sProtocol: 1185 intptr = &options->protocol; 1186 arg = strdelim(&cp); 1187 if (!arg || *arg == '\0') 1188 fatal("%s line %d: Missing argument.", filename, linenum); 1189 value = proto_spec(arg); 1190 if (value == SSH_PROTO_UNKNOWN) 1191 fatal("%s line %d: Bad protocol spec '%s'.", 1192 filename, linenum, arg ? arg : "<NONE>"); 1193 if (*intptr == SSH_PROTO_UNKNOWN) 1194 *intptr = value; 1195 break; 1196 1197 case sSubsystem: 1198 if (options->num_subsystems >= MAX_SUBSYSTEMS) { 1199 fatal("%s line %d: too many subsystems defined.", 1200 filename, linenum); 1201 } 1202 arg = strdelim(&cp); 1203 if (!arg || *arg == '\0') 1204 fatal("%s line %d: Missing subsystem name.", 1205 filename, linenum); 1206 if (!*activep) { 1207 arg = strdelim(&cp); 1208 break; 1209 } 1210 for (i = 0; i < options->num_subsystems; i++) 1211 if (strcmp(arg, options->subsystem_name[i]) == 0) 1212 fatal("%s line %d: Subsystem '%s' already defined.", 1213 filename, linenum, arg); 1214 options->subsystem_name[options->num_subsystems] = xstrdup(arg); 1215 arg = strdelim(&cp); 1216 if (!arg || *arg == '\0') 1217 fatal("%s line %d: Missing subsystem command.", 1218 filename, linenum); 1219 options->subsystem_command[options->num_subsystems] = xstrdup(arg); 1220 1221 /* Collect arguments (separate to executable) */ 1222 p = xstrdup(arg); 1223 len = strlen(p) + 1; 1224 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { 1225 len += 1 + strlen(arg); 1226 p = xrealloc(p, 1, len); 1227 strlcat(p, " ", len); 1228 strlcat(p, arg, len); 1229 } 1230 options->subsystem_args[options->num_subsystems] = p; 1231 options->num_subsystems++; 1232 break; 1233 1234 case sMaxStartups: 1235 arg = strdelim(&cp); 1236 if (!arg || *arg == '\0') 1237 fatal("%s line %d: Missing MaxStartups spec.", 1238 filename, linenum); 1239 if ((n = sscanf(arg, "%d:%d:%d", 1240 &options->max_startups_begin, 1241 &options->max_startups_rate, 1242 &options->max_startups)) == 3) { 1243 if (options->max_startups_begin > 1244 options->max_startups || 1245 options->max_startups_rate > 100 || 1246 options->max_startups_rate < 1) 1247 fatal("%s line %d: Illegal MaxStartups spec.", 1248 filename, linenum); 1249 } else if (n != 1) 1250 fatal("%s line %d: Illegal MaxStartups spec.", 1251 filename, linenum); 1252 else 1253 options->max_startups = options->max_startups_begin; 1254 break; 1255 1256 case sMaxAuthTries: 1257 intptr = &options->max_authtries; 1258 goto parse_int; 1259 1260 case sMaxSessions: 1261 intptr = &options->max_sessions; 1262 goto parse_int; 1263 1264 case sBanner: 1265 charptr = &options->banner; 1266 goto parse_filename; 1267 1268 /* 1269 * These options can contain %X options expanded at 1270 * connect time, so that you can specify paths like: 1271 * 1272 * AuthorizedKeysFile /etc/ssh_keys/%u 1273 */ 1274 case sAuthorizedKeysFile: 1275 if (*activep && options->num_authkeys_files == 0) { 1276 while ((arg = strdelim(&cp)) && *arg != '\0') { 1277 if (options->num_authkeys_files >= 1278 MAX_AUTHKEYS_FILES) 1279 fatal("%s line %d: " 1280 "too many authorized keys files.", 1281 filename, linenum); 1282 options->authorized_keys_files[ 1283 options->num_authkeys_files++] = 1284 tilde_expand_filename(arg, getuid()); 1285 } 1286 } 1287 return 0; 1288 1289 case sAuthorizedPrincipalsFile: 1290 charptr = &options->authorized_principals_file; 1291 arg = strdelim(&cp); 1292 if (!arg || *arg == '\0') 1293 fatal("%s line %d: missing file name.", 1294 filename, linenum); 1295 if (*activep && *charptr == NULL) { 1296 *charptr = tilde_expand_filename(arg, getuid()); 1297 /* increase optional counter */ 1298 if (intptr != NULL) 1299 *intptr = *intptr + 1; 1300 } 1301 break; 1302 1303 case sClientAliveInterval: 1304 intptr = &options->client_alive_interval; 1305 goto parse_time; 1306 1307 case sClientAliveCountMax: 1308 intptr = &options->client_alive_count_max; 1309 goto parse_int; 1310 1311 case sAcceptEnv: 1312 while ((arg = strdelim(&cp)) && *arg != '\0') { 1313 if (strchr(arg, '=') != NULL) 1314 fatal("%s line %d: Invalid environment name.", 1315 filename, linenum); 1316 if (options->num_accept_env >= MAX_ACCEPT_ENV) 1317 fatal("%s line %d: too many allow env.", 1318 filename, linenum); 1319 if (!*activep) 1320 continue; 1321 options->accept_env[options->num_accept_env++] = 1322 xstrdup(arg); 1323 } 1324 break; 1325 1326 case sPermitTunnel: 1327 intptr = &options->permit_tun; 1328 arg = strdelim(&cp); 1329 if (!arg || *arg == '\0') 1330 fatal("%s line %d: Missing yes/point-to-point/" 1331 "ethernet/no argument.", filename, linenum); 1332 value = -1; 1333 for (i = 0; tunmode_desc[i].val != -1; i++) 1334 if (strcmp(tunmode_desc[i].text, arg) == 0) { 1335 value = tunmode_desc[i].val; 1336 break; 1337 } 1338 if (value == -1) 1339 fatal("%s line %d: Bad yes/point-to-point/ethernet/" 1340 "no argument: %s", filename, linenum, arg); 1341 if (*intptr == -1) 1342 *intptr = value; 1343 break; 1344 1345 case sMatch: 1346 if (cmdline) 1347 fatal("Match directive not supported as a command-line " 1348 "option"); 1349 value = match_cfg_line(&cp, linenum, connectinfo); 1350 if (value < 0) 1351 fatal("%s line %d: Bad Match condition", filename, 1352 linenum); 1353 *activep = value; 1354 break; 1355 1356 case sPermitOpen: 1357 arg = strdelim(&cp); 1358 if (!arg || *arg == '\0') 1359 fatal("%s line %d: missing PermitOpen specification", 1360 filename, linenum); 1361 n = options->num_permitted_opens; /* modified later */ 1362 if (strcmp(arg, "any") == 0) { 1363 if (*activep && n == -1) { 1364 channel_clear_adm_permitted_opens(); 1365 options->num_permitted_opens = 0; 1366 } 1367 break; 1368 } 1369 if (strcmp(arg, "none") == 0) { 1370 if (*activep && n == -1) { 1371 channel_clear_adm_permitted_opens(); 1372 options->num_permitted_opens = 1; 1373 channel_disable_adm_local_opens(); 1374 } 1375 break; 1376 } 1377 if (*activep && n == -1) 1378 channel_clear_adm_permitted_opens(); 1379 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { 1380 p = hpdelim(&arg); 1381 if (p == NULL) 1382 fatal("%s line %d: missing host in PermitOpen", 1383 filename, linenum); 1384 p = cleanhostname(p); 1385 if (arg == NULL || ((port = permitopen_port(arg)) < 0)) 1386 fatal("%s line %d: bad port number in " 1387 "PermitOpen", filename, linenum); 1388 if (*activep && n == -1) 1389 options->num_permitted_opens = 1390 channel_add_adm_permitted_opens(p, port); 1391 } 1392 break; 1393 1394 case sForceCommand: 1395 if (cp == NULL) 1396 fatal("%.200s line %d: Missing argument.", filename, 1397 linenum); 1398 len = strspn(cp, WHITESPACE); 1399 if (*activep && options->adm_forced_command == NULL) 1400 options->adm_forced_command = xstrdup(cp + len); 1401 return 0; 1402 1403 case sChrootDirectory: 1404 charptr = &options->chroot_directory; 1405 1406 arg = strdelim(&cp); 1407 if (!arg || *arg == '\0') 1408 fatal("%s line %d: missing file name.", 1409 filename, linenum); 1410 if (*activep && *charptr == NULL) 1411 *charptr = xstrdup(arg); 1412 break; 1413 1414 case sTrustedUserCAKeys: 1415 charptr = &options->trusted_user_ca_keys; 1416 goto parse_filename; 1417 1418 case sRevokedKeys: 1419 charptr = &options->revoked_keys_file; 1420 goto parse_filename; 1421 1422 case sIPQoS: 1423 arg = strdelim(&cp); 1424 if ((value = parse_ipqos(arg)) == -1) 1425 fatal("%s line %d: Bad IPQoS value: %s", 1426 filename, linenum, arg); 1427 arg = strdelim(&cp); 1428 if (arg == NULL) 1429 value2 = value; 1430 else if ((value2 = parse_ipqos(arg)) == -1) 1431 fatal("%s line %d: Bad IPQoS value: %s", 1432 filename, linenum, arg); 1433 if (*activep) { 1434 options->ip_qos_interactive = value; 1435 options->ip_qos_bulk = value2; 1436 } 1437 break; 1438 1439 case sVersionAddendum: 1440 if (cp == NULL) 1441 fatal("%.200s line %d: Missing argument.", filename, 1442 linenum); 1443 len = strspn(cp, WHITESPACE); 1444 if (*activep && options->version_addendum == NULL) { 1445 if (strcasecmp(cp + len, "none") == 0) 1446 options->version_addendum = xstrdup(""); 1447 else if (strchr(cp + len, '\r') != NULL) 1448 fatal("%.200s line %d: Invalid argument", 1449 filename, linenum); 1450 else 1451 options->version_addendum = xstrdup(cp + len); 1452 } 1453 return 0; 1454 1455 case sDeprecated: 1456 logit("%s line %d: Deprecated option %s", 1457 filename, linenum, arg); 1458 while (arg) 1459 arg = strdelim(&cp); 1460 break; 1461 1462 case sUnsupported: 1463 logit("%s line %d: Unsupported option %s", 1464 filename, linenum, arg); 1465 while (arg) 1466 arg = strdelim(&cp); 1467 break; 1468 1469 default: 1470 fatal("%s line %d: Missing handler for opcode %s (%d)", 1471 filename, linenum, arg, opcode); 1472 } 1473 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') 1474 fatal("%s line %d: garbage at end of line; \"%.200s\".", 1475 filename, linenum, arg); 1476 return 0; 1477 } 1478 1479 /* Reads the server configuration file. */ 1480 1481 void 1482 load_server_config(const char *filename, Buffer *conf) 1483 { 1484 char line[4096], *cp; 1485 FILE *f; 1486 int lineno = 0; 1487 1488 debug2("%s: filename %s", __func__, filename); 1489 if ((f = fopen(filename, "r")) == NULL) { 1490 perror(filename); 1491 exit(1); 1492 } 1493 buffer_clear(conf); 1494 while (fgets(line, sizeof(line), f)) { 1495 lineno++; 1496 if (strlen(line) == sizeof(line) - 1) 1497 fatal("%s line %d too long", filename, lineno); 1498 /* 1499 * Trim out comments and strip whitespace 1500 * NB - preserve newlines, they are needed to reproduce 1501 * line numbers later for error messages 1502 */ 1503 if ((cp = strchr(line, '#')) != NULL) 1504 memcpy(cp, "\n", 2); 1505 cp = line + strspn(line, " \t\r"); 1506 1507 buffer_append(conf, cp, strlen(cp)); 1508 } 1509 buffer_append(conf, "\0", 1); 1510 fclose(f); 1511 debug2("%s: done config len = %d", __func__, buffer_len(conf)); 1512 } 1513 1514 void 1515 parse_server_match_config(ServerOptions *options, 1516 struct connection_info *connectinfo) 1517 { 1518 ServerOptions mo; 1519 1520 initialize_server_options(&mo); 1521 parse_server_config(&mo, "reprocess config", &cfg, connectinfo); 1522 copy_set_server_options(options, &mo, 0); 1523 } 1524 1525 int parse_server_match_testspec(struct connection_info *ci, char *spec) 1526 { 1527 char *p; 1528 1529 while ((p = strsep(&spec, ",")) && *p != '\0') { 1530 if (strncmp(p, "addr=", 5) == 0) { 1531 ci->address = xstrdup(p + 5); 1532 } else if (strncmp(p, "host=", 5) == 0) { 1533 ci->host = xstrdup(p + 5); 1534 } else if (strncmp(p, "user=", 5) == 0) { 1535 ci->user = xstrdup(p + 5); 1536 } else if (strncmp(p, "laddr=", 6) == 0) { 1537 ci->laddress = xstrdup(p + 6); 1538 } else if (strncmp(p, "lport=", 6) == 0) { 1539 ci->lport = a2port(p + 6); 1540 if (ci->lport == -1) { 1541 fprintf(stderr, "Invalid port '%s' in test mode" 1542 " specification %s\n", p+6, p); 1543 return -1; 1544 } 1545 } else { 1546 fprintf(stderr, "Invalid test mode specification %s\n", 1547 p); 1548 return -1; 1549 } 1550 } 1551 return 0; 1552 } 1553 1554 /* 1555 * returns 1 for a complete spec, 0 for partial spec and -1 for an 1556 * empty spec. 1557 */ 1558 int server_match_spec_complete(struct connection_info *ci) 1559 { 1560 if (ci->user && ci->host && ci->address) 1561 return 1; /* complete */ 1562 if (!ci->user && !ci->host && !ci->address) 1563 return -1; /* empty */ 1564 return 0; /* partial */ 1565 } 1566 1567 /* Helper macros */ 1568 #define M_CP_INTOPT(n) do {\ 1569 if (src->n != -1) \ 1570 dst->n = src->n; \ 1571 } while (0) 1572 #define M_CP_STROPT(n) do {\ 1573 if (src->n != NULL) { \ 1574 if (dst->n != NULL) \ 1575 xfree(dst->n); \ 1576 dst->n = src->n; \ 1577 } \ 1578 } while(0) 1579 #define M_CP_STRARRAYOPT(n, num_n) do {\ 1580 if (src->num_n != 0) { \ 1581 for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ 1582 dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ 1583 } \ 1584 } while(0) 1585 1586 /* 1587 * Copy any supported values that are set. 1588 * 1589 * If the preauth flag is set, we do not bother copying the string or 1590 * array values that are not used pre-authentication, because any that we 1591 * do use must be explictly sent in mm_getpwnamallow(). 1592 */ 1593 void 1594 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) 1595 { 1596 M_CP_INTOPT(password_authentication); 1597 M_CP_INTOPT(gss_authentication); 1598 M_CP_INTOPT(rsa_authentication); 1599 M_CP_INTOPT(pubkey_authentication); 1600 M_CP_INTOPT(kerberos_authentication); 1601 M_CP_INTOPT(hostbased_authentication); 1602 M_CP_INTOPT(hostbased_uses_name_from_packet_only); 1603 M_CP_INTOPT(kbd_interactive_authentication); 1604 M_CP_INTOPT(zero_knowledge_password_authentication); 1605 M_CP_INTOPT(permit_root_login); 1606 M_CP_INTOPT(permit_empty_passwd); 1607 1608 M_CP_INTOPT(allow_tcp_forwarding); 1609 M_CP_INTOPT(allow_agent_forwarding); 1610 M_CP_INTOPT(permit_tun); 1611 M_CP_INTOPT(gateway_ports); 1612 M_CP_INTOPT(x11_display_offset); 1613 M_CP_INTOPT(x11_forwarding); 1614 M_CP_INTOPT(x11_use_localhost); 1615 M_CP_INTOPT(max_sessions); 1616 M_CP_INTOPT(max_authtries); 1617 M_CP_INTOPT(ip_qos_interactive); 1618 M_CP_INTOPT(ip_qos_bulk); 1619 1620 /* See comment in servconf.h */ 1621 COPY_MATCH_STRING_OPTS(); 1622 1623 /* 1624 * The only things that should be below this point are string options 1625 * which are only used after authentication. 1626 */ 1627 if (preauth) 1628 return; 1629 1630 M_CP_STROPT(adm_forced_command); 1631 M_CP_STROPT(chroot_directory); 1632 } 1633 1634 #undef M_CP_INTOPT 1635 #undef M_CP_STROPT 1636 #undef M_CP_STRARRAYOPT 1637 1638 void 1639 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, 1640 struct connection_info *connectinfo) 1641 { 1642 int active, linenum, bad_options = 0; 1643 char *cp, *obuf, *cbuf; 1644 1645 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); 1646 1647 obuf = cbuf = xstrdup(buffer_ptr(conf)); 1648 active = connectinfo ? 0 : 1; 1649 linenum = 1; 1650 while ((cp = strsep(&cbuf, "\n")) != NULL) { 1651 if (process_server_config_line(options, cp, filename, 1652 linenum++, &active, connectinfo) != 0) 1653 bad_options++; 1654 } 1655 xfree(obuf); 1656 if (bad_options > 0) 1657 fatal("%s: terminating, %d bad configuration options", 1658 filename, bad_options); 1659 } 1660 1661 static const char * 1662 fmt_multistate_int(int val, const struct multistate *m) 1663 { 1664 u_int i; 1665 1666 for (i = 0; m[i].key != NULL; i++) { 1667 if (m[i].value == val) 1668 return m[i].key; 1669 } 1670 return "UNKNOWN"; 1671 } 1672 1673 static const char * 1674 fmt_intarg(ServerOpCodes code, int val) 1675 { 1676 if (val == -1) 1677 return "unset"; 1678 switch (code) { 1679 case sAddressFamily: 1680 return fmt_multistate_int(val, multistate_addressfamily); 1681 case sPermitRootLogin: 1682 return fmt_multistate_int(val, multistate_permitrootlogin); 1683 case sGatewayPorts: 1684 return fmt_multistate_int(val, multistate_gatewayports); 1685 case sCompression: 1686 return fmt_multistate_int(val, multistate_compression); 1687 case sUsePrivilegeSeparation: 1688 return fmt_multistate_int(val, multistate_privsep); 1689 case sProtocol: 1690 switch (val) { 1691 case SSH_PROTO_1: 1692 return "1"; 1693 case SSH_PROTO_2: 1694 return "2"; 1695 case (SSH_PROTO_1|SSH_PROTO_2): 1696 return "2,1"; 1697 default: 1698 return "UNKNOWN"; 1699 } 1700 default: 1701 switch (val) { 1702 case 0: 1703 return "no"; 1704 case 1: 1705 return "yes"; 1706 default: 1707 return "UNKNOWN"; 1708 } 1709 } 1710 } 1711 1712 static const char * 1713 lookup_opcode_name(ServerOpCodes code) 1714 { 1715 u_int i; 1716 1717 for (i = 0; keywords[i].name != NULL; i++) 1718 if (keywords[i].opcode == code) 1719 return(keywords[i].name); 1720 return "UNKNOWN"; 1721 } 1722 1723 static void 1724 dump_cfg_int(ServerOpCodes code, int val) 1725 { 1726 printf("%s %d\n", lookup_opcode_name(code), val); 1727 } 1728 1729 static void 1730 dump_cfg_fmtint(ServerOpCodes code, int val) 1731 { 1732 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 1733 } 1734 1735 static void 1736 dump_cfg_string(ServerOpCodes code, const char *val) 1737 { 1738 if (val == NULL) 1739 return; 1740 printf("%s %s\n", lookup_opcode_name(code), val); 1741 } 1742 1743 static void 1744 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) 1745 { 1746 u_int i; 1747 1748 for (i = 0; i < count; i++) 1749 printf("%s %s\n", lookup_opcode_name(code), vals[i]); 1750 } 1751 1752 static void 1753 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals) 1754 { 1755 u_int i; 1756 1757 printf("%s", lookup_opcode_name(code)); 1758 for (i = 0; i < count; i++) 1759 printf(" %s", vals[i]); 1760 printf("\n"); 1761 } 1762 1763 void 1764 dump_config(ServerOptions *o) 1765 { 1766 u_int i; 1767 int ret; 1768 struct addrinfo *ai; 1769 char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; 1770 1771 /* these are usually at the top of the config */ 1772 for (i = 0; i < o->num_ports; i++) 1773 printf("port %d\n", o->ports[i]); 1774 dump_cfg_fmtint(sProtocol, o->protocol); 1775 dump_cfg_fmtint(sAddressFamily, o->address_family); 1776 1777 /* ListenAddress must be after Port */ 1778 for (ai = o->listen_addrs; ai; ai = ai->ai_next) { 1779 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, 1780 sizeof(addr), port, sizeof(port), 1781 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 1782 error("getnameinfo failed: %.100s", 1783 (ret != EAI_SYSTEM) ? gai_strerror(ret) : 1784 strerror(errno)); 1785 } else { 1786 if (ai->ai_family == AF_INET6) 1787 printf("listenaddress [%s]:%s\n", addr, port); 1788 else 1789 printf("listenaddress %s:%s\n", addr, port); 1790 } 1791 } 1792 1793 /* integer arguments */ 1794 dump_cfg_int(sServerKeyBits, o->server_key_bits); 1795 dump_cfg_int(sLoginGraceTime, o->login_grace_time); 1796 dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); 1797 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); 1798 dump_cfg_int(sMaxAuthTries, o->max_authtries); 1799 dump_cfg_int(sMaxSessions, o->max_sessions); 1800 dump_cfg_int(sClientAliveInterval, o->client_alive_interval); 1801 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); 1802 1803 /* formatted integer arguments */ 1804 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); 1805 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); 1806 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); 1807 dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication); 1808 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); 1809 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, 1810 o->hostbased_uses_name_from_packet_only); 1811 dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication); 1812 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); 1813 #ifdef KRB5 1814 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); 1815 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); 1816 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); 1817 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); 1818 #endif 1819 #ifdef GSSAPI 1820 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); 1821 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); 1822 #endif 1823 #ifdef JPAKE 1824 dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication, 1825 o->zero_knowledge_password_authentication); 1826 #endif 1827 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); 1828 dump_cfg_fmtint(sKbdInteractiveAuthentication, 1829 o->kbd_interactive_authentication); 1830 dump_cfg_fmtint(sChallengeResponseAuthentication, 1831 o->challenge_response_authentication); 1832 dump_cfg_fmtint(sPrintMotd, o->print_motd); 1833 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); 1834 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); 1835 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); 1836 dump_cfg_fmtint(sStrictModes, o->strict_modes); 1837 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); 1838 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); 1839 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); 1840 dump_cfg_fmtint(sUseLogin, o->use_login); 1841 dump_cfg_fmtint(sCompression, o->compression); 1842 dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); 1843 dump_cfg_fmtint(sUseDNS, o->use_dns); 1844 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); 1845 dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); 1846 1847 /* string arguments */ 1848 dump_cfg_string(sPidFile, o->pid_file); 1849 dump_cfg_string(sXAuthLocation, o->xauth_location); 1850 dump_cfg_string(sCiphers, o->ciphers); 1851 dump_cfg_string(sMacs, o->macs); 1852 dump_cfg_string(sBanner, o->banner); 1853 dump_cfg_string(sForceCommand, o->adm_forced_command); 1854 dump_cfg_string(sChrootDirectory, o->chroot_directory); 1855 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); 1856 dump_cfg_string(sRevokedKeys, o->revoked_keys_file); 1857 dump_cfg_string(sAuthorizedPrincipalsFile, 1858 o->authorized_principals_file); 1859 dump_cfg_string(sVersionAddendum, o->version_addendum); 1860 1861 /* string arguments requiring a lookup */ 1862 dump_cfg_string(sLogLevel, log_level_name(o->log_level)); 1863 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); 1864 1865 /* string array arguments */ 1866 dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files, 1867 o->authorized_keys_files); 1868 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, 1869 o->host_key_files); 1870 dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files, 1871 o->host_cert_files); 1872 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); 1873 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); 1874 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); 1875 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); 1876 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); 1877 1878 /* other arguments */ 1879 for (i = 0; i < o->num_subsystems; i++) 1880 printf("subsystem %s %s\n", o->subsystem_name[i], 1881 o->subsystem_args[i]); 1882 1883 printf("maxstartups %d:%d:%d\n", o->max_startups_begin, 1884 o->max_startups_rate, o->max_startups); 1885 1886 for (i = 0; tunmode_desc[i].val != -1; i++) 1887 if (tunmode_desc[i].val == o->permit_tun) { 1888 s = tunmode_desc[i].text; 1889 break; 1890 } 1891 dump_cfg_string(sPermitTunnel, s); 1892 1893 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 1894 printf("%s\n", iptos2str(o->ip_qos_bulk)); 1895 1896 channel_print_adm_permitted_opens(); 1897 } 1898