1 2 /* $OpenBSD: servconf.c,v 1.351 2019/04/18 18:56:16 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 #include <sys/sysctl.h> 18 19 #include <netinet/in.h> 20 #include <netinet/ip.h> 21 #include <net/route.h> 22 23 #include <ctype.h> 24 #include <netdb.h> 25 #include <pwd.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <signal.h> 30 #include <unistd.h> 31 #include <limits.h> 32 #include <stdarg.h> 33 #include <errno.h> 34 #include <util.h> 35 36 #include "xmalloc.h" 37 #include "ssh.h" 38 #include "log.h" 39 #include "sshbuf.h" 40 #include "misc.h" 41 #include "servconf.h" 42 #include "compat.h" 43 #include "pathnames.h" 44 #include "cipher.h" 45 #include "sshkey.h" 46 #include "kex.h" 47 #include "mac.h" 48 #include "match.h" 49 #include "channels.h" 50 #include "groupaccess.h" 51 #include "canohost.h" 52 #include "packet.h" 53 #include "ssherr.h" 54 #include "hostfile.h" 55 #include "auth.h" 56 #include "myproposal.h" 57 #include "digest.h" 58 59 static void add_listen_addr(ServerOptions *, const char *, 60 const char *, int); 61 static void add_one_listen_addr(ServerOptions *, const char *, 62 const char *, int); 63 64 /* Use of privilege separation or not */ 65 extern int use_privsep; 66 extern struct sshbuf *cfg; 67 68 /* Initializes the server options to their default values. */ 69 70 void 71 initialize_server_options(ServerOptions *options) 72 { 73 memset(options, 0, sizeof(*options)); 74 options->num_ports = 0; 75 options->ports_from_cmdline = 0; 76 options->queued_listen_addrs = NULL; 77 options->num_queued_listens = 0; 78 options->listen_addrs = NULL; 79 options->num_listen_addrs = 0; 80 options->address_family = -1; 81 options->routing_domain = NULL; 82 options->num_host_key_files = 0; 83 options->num_host_cert_files = 0; 84 options->host_key_agent = NULL; 85 options->pid_file = NULL; 86 options->login_grace_time = -1; 87 options->permit_root_login = PERMIT_NOT_SET; 88 options->ignore_rhosts = -1; 89 options->ignore_user_known_hosts = -1; 90 options->print_motd = -1; 91 options->print_lastlog = -1; 92 options->x11_forwarding = -1; 93 options->x11_display_offset = -1; 94 options->x11_use_localhost = -1; 95 options->permit_tty = -1; 96 options->permit_user_rc = -1; 97 options->xauth_location = NULL; 98 options->strict_modes = -1; 99 options->tcp_keep_alive = -1; 100 options->log_facility = SYSLOG_FACILITY_NOT_SET; 101 options->log_level = SYSLOG_LEVEL_NOT_SET; 102 options->hostbased_authentication = -1; 103 options->hostbased_uses_name_from_packet_only = -1; 104 options->hostbased_key_types = NULL; 105 options->hostkeyalgorithms = NULL; 106 options->pubkey_authentication = -1; 107 options->pubkey_key_types = NULL; 108 options->kerberos_authentication = -1; 109 options->kerberos_or_local_passwd = -1; 110 options->kerberos_ticket_cleanup = -1; 111 options->kerberos_get_afs_token = -1; 112 options->gss_authentication=-1; 113 options->gss_cleanup_creds = -1; 114 options->gss_strict_acceptor = -1; 115 options->password_authentication = -1; 116 options->kbd_interactive_authentication = -1; 117 options->challenge_response_authentication = -1; 118 options->permit_empty_passwd = -1; 119 options->permit_user_env = -1; 120 options->permit_user_env_whitelist = NULL; 121 options->compression = -1; 122 options->rekey_limit = -1; 123 options->rekey_interval = -1; 124 options->allow_tcp_forwarding = -1; 125 options->allow_streamlocal_forwarding = -1; 126 options->allow_agent_forwarding = -1; 127 options->num_allow_users = 0; 128 options->num_deny_users = 0; 129 options->num_allow_groups = 0; 130 options->num_deny_groups = 0; 131 options->ciphers = NULL; 132 options->macs = NULL; 133 options->kex_algorithms = NULL; 134 options->ca_sign_algorithms = NULL; 135 options->fwd_opts.gateway_ports = -1; 136 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; 137 options->fwd_opts.streamlocal_bind_unlink = -1; 138 options->num_subsystems = 0; 139 options->max_startups_begin = -1; 140 options->max_startups_rate = -1; 141 options->max_startups = -1; 142 options->max_authtries = -1; 143 options->max_sessions = -1; 144 options->banner = NULL; 145 options->use_dns = -1; 146 options->client_alive_interval = -1; 147 options->client_alive_count_max = -1; 148 options->num_authkeys_files = 0; 149 options->num_accept_env = 0; 150 options->num_setenv = 0; 151 options->permit_tun = -1; 152 options->permitted_opens = NULL; 153 options->permitted_listens = NULL; 154 options->adm_forced_command = NULL; 155 options->chroot_directory = NULL; 156 options->authorized_keys_command = NULL; 157 options->authorized_keys_command_user = NULL; 158 options->revoked_keys_file = NULL; 159 options->trusted_user_ca_keys = NULL; 160 options->authorized_principals_file = NULL; 161 options->authorized_principals_command = NULL; 162 options->authorized_principals_command_user = NULL; 163 options->ip_qos_interactive = -1; 164 options->ip_qos_bulk = -1; 165 options->version_addendum = NULL; 166 options->fingerprint_hash = -1; 167 options->disable_forwarding = -1; 168 options->expose_userauth_info = -1; 169 } 170 171 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ 172 static int 173 option_clear_or_none(const char *o) 174 { 175 return o == NULL || strcasecmp(o, "none") == 0; 176 } 177 178 static void 179 assemble_algorithms(ServerOptions *o) 180 { 181 char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig; 182 int r; 183 184 all_cipher = cipher_alg_list(',', 0); 185 all_mac = mac_alg_list(','); 186 all_kex = kex_alg_list(','); 187 all_key = sshkey_alg_list(0, 0, 1, ','); 188 all_sig = sshkey_alg_list(0, 1, 1, ','); 189 #define ASSEMBLE(what, defaults, all) \ 190 do { \ 191 if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ 192 fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ 193 } while (0) 194 ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); 195 ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); 196 ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); 197 ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key); 198 ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); 199 ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); 200 ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); 201 #undef ASSEMBLE 202 free(all_cipher); 203 free(all_mac); 204 free(all_kex); 205 free(all_key); 206 free(all_sig); 207 } 208 209 static void 210 array_append2(const char *file, const int line, const char *directive, 211 char ***array, int **iarray, u_int *lp, const char *s, int i) 212 { 213 214 if (*lp >= INT_MAX) 215 fatal("%s line %d: Too many %s entries", file, line, directive); 216 217 if (iarray != NULL) { 218 *iarray = xrecallocarray(*iarray, *lp, *lp + 1, 219 sizeof(**iarray)); 220 (*iarray)[*lp] = i; 221 } 222 223 *array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array)); 224 (*array)[*lp] = xstrdup(s); 225 (*lp)++; 226 } 227 228 static void 229 array_append(const char *file, const int line, const char *directive, 230 char ***array, u_int *lp, const char *s) 231 { 232 array_append2(file, line, directive, array, NULL, lp, s, 0); 233 } 234 235 void 236 servconf_add_hostkey(const char *file, const int line, 237 ServerOptions *options, const char *path, int userprovided) 238 { 239 char *apath = derelativise_path(path); 240 241 array_append2(file, line, "HostKey", 242 &options->host_key_files, &options->host_key_file_userprovided, 243 &options->num_host_key_files, apath, userprovided); 244 free(apath); 245 } 246 247 void 248 servconf_add_hostcert(const char *file, const int line, 249 ServerOptions *options, const char *path) 250 { 251 char *apath = derelativise_path(path); 252 253 array_append(file, line, "HostCertificate", 254 &options->host_cert_files, &options->num_host_cert_files, apath); 255 free(apath); 256 } 257 258 void 259 fill_default_server_options(ServerOptions *options) 260 { 261 u_int i; 262 263 if (options->num_host_key_files == 0) { 264 /* fill default hostkeys */ 265 servconf_add_hostkey("[default]", 0, options, 266 _PATH_HOST_RSA_KEY_FILE, 0); 267 servconf_add_hostkey("[default]", 0, options, 268 _PATH_HOST_ECDSA_KEY_FILE, 0); 269 servconf_add_hostkey("[default]", 0, options, 270 _PATH_HOST_ED25519_KEY_FILE, 0); 271 #ifdef WITH_XMSS 272 servconf_add_hostkey("[default]", 0, options, 273 _PATH_HOST_XMSS_KEY_FILE, 0); 274 #endif /* WITH_XMSS */ 275 } 276 /* No certificates by default */ 277 if (options->num_ports == 0) 278 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 279 if (options->address_family == -1) 280 options->address_family = AF_UNSPEC; 281 if (options->listen_addrs == NULL) 282 add_listen_addr(options, NULL, NULL, 0); 283 if (options->pid_file == NULL) 284 options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE); 285 if (options->login_grace_time == -1) 286 options->login_grace_time = 120; 287 if (options->permit_root_login == PERMIT_NOT_SET) 288 options->permit_root_login = PERMIT_NO_PASSWD; 289 if (options->ignore_rhosts == -1) 290 options->ignore_rhosts = 1; 291 if (options->ignore_user_known_hosts == -1) 292 options->ignore_user_known_hosts = 0; 293 if (options->print_motd == -1) 294 options->print_motd = 1; 295 if (options->print_lastlog == -1) 296 options->print_lastlog = 1; 297 if (options->x11_forwarding == -1) 298 options->x11_forwarding = 0; 299 if (options->x11_display_offset == -1) 300 options->x11_display_offset = 10; 301 if (options->x11_use_localhost == -1) 302 options->x11_use_localhost = 1; 303 if (options->xauth_location == NULL) 304 options->xauth_location = xstrdup(_PATH_XAUTH); 305 if (options->permit_tty == -1) 306 options->permit_tty = 1; 307 if (options->permit_user_rc == -1) 308 options->permit_user_rc = 1; 309 if (options->strict_modes == -1) 310 options->strict_modes = 1; 311 if (options->tcp_keep_alive == -1) 312 options->tcp_keep_alive = 1; 313 if (options->log_facility == SYSLOG_FACILITY_NOT_SET) 314 options->log_facility = SYSLOG_FACILITY_AUTH; 315 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 316 options->log_level = SYSLOG_LEVEL_INFO; 317 if (options->hostbased_authentication == -1) 318 options->hostbased_authentication = 0; 319 if (options->hostbased_uses_name_from_packet_only == -1) 320 options->hostbased_uses_name_from_packet_only = 0; 321 if (options->pubkey_authentication == -1) 322 options->pubkey_authentication = 1; 323 if (options->kerberos_authentication == -1) 324 options->kerberos_authentication = 0; 325 if (options->kerberos_or_local_passwd == -1) 326 options->kerberos_or_local_passwd = 1; 327 if (options->kerberos_ticket_cleanup == -1) 328 options->kerberos_ticket_cleanup = 1; 329 if (options->kerberos_get_afs_token == -1) 330 options->kerberos_get_afs_token = 0; 331 if (options->gss_authentication == -1) 332 options->gss_authentication = 0; 333 if (options->gss_cleanup_creds == -1) 334 options->gss_cleanup_creds = 1; 335 if (options->gss_strict_acceptor == -1) 336 options->gss_strict_acceptor = 1; 337 if (options->password_authentication == -1) 338 options->password_authentication = 1; 339 if (options->kbd_interactive_authentication == -1) 340 options->kbd_interactive_authentication = 0; 341 if (options->challenge_response_authentication == -1) 342 options->challenge_response_authentication = 1; 343 if (options->permit_empty_passwd == -1) 344 options->permit_empty_passwd = 0; 345 if (options->permit_user_env == -1) { 346 options->permit_user_env = 0; 347 options->permit_user_env_whitelist = NULL; 348 } 349 if (options->compression == -1) 350 options->compression = COMP_DELAYED; 351 if (options->rekey_limit == -1) 352 options->rekey_limit = 0; 353 if (options->rekey_interval == -1) 354 options->rekey_interval = 0; 355 if (options->allow_tcp_forwarding == -1) 356 options->allow_tcp_forwarding = FORWARD_ALLOW; 357 if (options->allow_streamlocal_forwarding == -1) 358 options->allow_streamlocal_forwarding = FORWARD_ALLOW; 359 if (options->allow_agent_forwarding == -1) 360 options->allow_agent_forwarding = 1; 361 if (options->fwd_opts.gateway_ports == -1) 362 options->fwd_opts.gateway_ports = 0; 363 if (options->max_startups == -1) 364 options->max_startups = 100; 365 if (options->max_startups_rate == -1) 366 options->max_startups_rate = 30; /* 30% */ 367 if (options->max_startups_begin == -1) 368 options->max_startups_begin = 10; 369 if (options->max_authtries == -1) 370 options->max_authtries = DEFAULT_AUTH_FAIL_MAX; 371 if (options->max_sessions == -1) 372 options->max_sessions = DEFAULT_SESSIONS_MAX; 373 if (options->use_dns == -1) 374 options->use_dns = 0; 375 if (options->client_alive_interval == -1) 376 options->client_alive_interval = 0; 377 if (options->client_alive_count_max == -1) 378 options->client_alive_count_max = 3; 379 if (options->num_authkeys_files == 0) { 380 array_append("[default]", 0, "AuthorizedKeysFiles", 381 &options->authorized_keys_files, 382 &options->num_authkeys_files, 383 _PATH_SSH_USER_PERMITTED_KEYS); 384 array_append("[default]", 0, "AuthorizedKeysFiles", 385 &options->authorized_keys_files, 386 &options->num_authkeys_files, 387 _PATH_SSH_USER_PERMITTED_KEYS2); 388 } 389 if (options->permit_tun == -1) 390 options->permit_tun = SSH_TUNMODE_NO; 391 if (options->ip_qos_interactive == -1) 392 options->ip_qos_interactive = IPTOS_DSCP_AF21; 393 if (options->ip_qos_bulk == -1) 394 options->ip_qos_bulk = IPTOS_DSCP_CS1; 395 if (options->version_addendum == NULL) 396 options->version_addendum = xstrdup(""); 397 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) 398 options->fwd_opts.streamlocal_bind_mask = 0177; 399 if (options->fwd_opts.streamlocal_bind_unlink == -1) 400 options->fwd_opts.streamlocal_bind_unlink = 0; 401 if (options->fingerprint_hash == -1) 402 options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 403 if (options->disable_forwarding == -1) 404 options->disable_forwarding = 0; 405 if (options->expose_userauth_info == -1) 406 options->expose_userauth_info = 0; 407 408 assemble_algorithms(options); 409 410 /* Turn privilege separation and sandboxing on by default */ 411 if (use_privsep == -1) 412 use_privsep = PRIVSEP_ON; 413 414 #define CLEAR_ON_NONE(v) \ 415 do { \ 416 if (option_clear_or_none(v)) { \ 417 free(v); \ 418 v = NULL; \ 419 } \ 420 } while(0) 421 CLEAR_ON_NONE(options->pid_file); 422 CLEAR_ON_NONE(options->xauth_location); 423 CLEAR_ON_NONE(options->banner); 424 CLEAR_ON_NONE(options->trusted_user_ca_keys); 425 CLEAR_ON_NONE(options->revoked_keys_file); 426 CLEAR_ON_NONE(options->authorized_principals_file); 427 CLEAR_ON_NONE(options->adm_forced_command); 428 CLEAR_ON_NONE(options->chroot_directory); 429 CLEAR_ON_NONE(options->routing_domain); 430 for (i = 0; i < options->num_host_key_files; i++) 431 CLEAR_ON_NONE(options->host_key_files[i]); 432 for (i = 0; i < options->num_host_cert_files; i++) 433 CLEAR_ON_NONE(options->host_cert_files[i]); 434 #undef CLEAR_ON_NONE 435 436 /* Similar handling for AuthenticationMethods=any */ 437 if (options->num_auth_methods == 1 && 438 strcmp(options->auth_methods[0], "any") == 0) { 439 free(options->auth_methods[0]); 440 options->auth_methods[0] = NULL; 441 options->num_auth_methods = 0; 442 } 443 } 444 445 /* Keyword tokens. */ 446 typedef enum { 447 sBadOption, /* == unknown option */ 448 sPort, sHostKeyFile, sLoginGraceTime, 449 sPermitRootLogin, sLogFacility, sLogLevel, 450 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 451 sKerberosGetAFSToken, sChallengeResponseAuthentication, 452 sPasswordAuthentication, sKbdInteractiveAuthentication, 453 sListenAddress, sAddressFamily, 454 sPrintMotd, sPrintLastLog, sIgnoreRhosts, 455 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, 456 sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, 457 sPermitUserEnvironment, sAllowTcpForwarding, sCompression, 458 sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 459 sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, 460 sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, 461 sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, 462 sBanner, sUseDNS, sHostbasedAuthentication, 463 sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, 464 sHostKeyAlgorithms, 465 sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, 466 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, 467 sAcceptEnv, sSetEnv, sPermitTunnel, 468 sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, 469 sUsePrivilegeSeparation, sAllowAgentForwarding, 470 sHostCertificate, 471 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, 472 sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, 473 sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum, 474 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, 475 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, 476 sStreamLocalBindMask, sStreamLocalBindUnlink, 477 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, 478 sExposeAuthInfo, sRDomain, 479 sDeprecated, sIgnore, sUnsupported 480 } ServerOpCodes; 481 482 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ 483 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ 484 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) 485 486 /* Textual representation of the tokens. */ 487 static struct { 488 const char *name; 489 ServerOpCodes opcode; 490 u_int flags; 491 } keywords[] = { 492 { "port", sPort, SSHCFG_GLOBAL }, 493 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, 494 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ 495 { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL }, 496 { "pidfile", sPidFile, SSHCFG_GLOBAL }, 497 { "serverkeybits", sDeprecated, SSHCFG_GLOBAL }, 498 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, 499 { "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL }, 500 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, 501 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, 502 { "loglevel", sLogLevel, SSHCFG_ALL }, 503 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, 504 { "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL }, 505 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, 506 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL }, 507 { "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL }, 508 { "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL }, 509 { "rsaauthentication", sDeprecated, SSHCFG_ALL }, 510 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, 511 { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, 512 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ 513 #ifdef KRB5 514 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, 515 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL }, 516 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL }, 517 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL }, 518 #else 519 { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, 520 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, 521 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, 522 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, 523 #endif 524 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, 525 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, 526 #ifdef GSSAPI 527 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, 528 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, 529 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, 530 #else 531 { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, 532 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, 533 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, 534 #endif 535 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, 536 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, 537 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, 538 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ 539 { "checkmail", sDeprecated, SSHCFG_GLOBAL }, 540 { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, 541 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, 542 { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, 543 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL }, 544 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL }, 545 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, 546 { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, 547 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, 548 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, 549 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, 550 { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, 551 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, 552 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, 553 { "uselogin", sDeprecated, SSHCFG_GLOBAL }, 554 { "compression", sCompression, SSHCFG_GLOBAL }, 555 { "rekeylimit", sRekeyLimit, SSHCFG_ALL }, 556 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, 557 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ 558 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, 559 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL }, 560 { "allowusers", sAllowUsers, SSHCFG_ALL }, 561 { "denyusers", sDenyUsers, SSHCFG_ALL }, 562 { "allowgroups", sAllowGroups, SSHCFG_ALL }, 563 { "denygroups", sDenyGroups, SSHCFG_ALL }, 564 { "ciphers", sCiphers, SSHCFG_GLOBAL }, 565 { "macs", sMacs, SSHCFG_GLOBAL }, 566 { "protocol", sIgnore, SSHCFG_GLOBAL }, 567 { "gatewayports", sGatewayPorts, SSHCFG_ALL }, 568 { "subsystem", sSubsystem, SSHCFG_GLOBAL }, 569 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, 570 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, 571 { "maxsessions", sMaxSessions, SSHCFG_ALL }, 572 { "banner", sBanner, SSHCFG_ALL }, 573 { "usedns", sUseDNS, SSHCFG_GLOBAL }, 574 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, 575 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, 576 { "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL }, 577 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL }, 578 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, 579 { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, 580 { "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL}, 581 { "acceptenv", sAcceptEnv, SSHCFG_ALL }, 582 { "setenv", sSetEnv, SSHCFG_ALL }, 583 { "permittunnel", sPermitTunnel, SSHCFG_ALL }, 584 { "permittty", sPermitTTY, SSHCFG_ALL }, 585 { "permituserrc", sPermitUserRC, SSHCFG_ALL }, 586 { "match", sMatch, SSHCFG_ALL }, 587 { "permitopen", sPermitOpen, SSHCFG_ALL }, 588 { "permitlisten", sPermitListen, SSHCFG_ALL }, 589 { "forcecommand", sForceCommand, SSHCFG_ALL }, 590 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, 591 { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, 592 { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, 593 { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, 594 { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, 595 { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, 596 { "ipqos", sIPQoS, SSHCFG_ALL }, 597 { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, 598 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, 599 { "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL }, 600 { "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL }, 601 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, 602 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, 603 { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, 604 { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, 605 { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, 606 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, 607 { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, 608 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, 609 { "rdomain", sRDomain, SSHCFG_ALL }, 610 { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, 611 { NULL, sBadOption, 0 } 612 }; 613 614 static struct { 615 int val; 616 char *text; 617 } tunmode_desc[] = { 618 { SSH_TUNMODE_NO, "no" }, 619 { SSH_TUNMODE_POINTOPOINT, "point-to-point" }, 620 { SSH_TUNMODE_ETHERNET, "ethernet" }, 621 { SSH_TUNMODE_YES, "yes" }, 622 { -1, NULL } 623 }; 624 625 /* Returns an opcode name from its number */ 626 627 static const char * 628 lookup_opcode_name(ServerOpCodes code) 629 { 630 u_int i; 631 632 for (i = 0; keywords[i].name != NULL; i++) 633 if (keywords[i].opcode == code) 634 return(keywords[i].name); 635 return "UNKNOWN"; 636 } 637 638 639 /* 640 * Returns the number of the token pointed to by cp or sBadOption. 641 */ 642 643 static ServerOpCodes 644 parse_token(const char *cp, const char *filename, 645 int linenum, u_int *flags) 646 { 647 u_int i; 648 649 for (i = 0; keywords[i].name; i++) 650 if (strcasecmp(cp, keywords[i].name) == 0) { 651 *flags = keywords[i].flags; 652 return keywords[i].opcode; 653 } 654 655 error("%s: line %d: Bad configuration option: %s", 656 filename, linenum, cp); 657 return sBadOption; 658 } 659 660 char * 661 derelativise_path(const char *path) 662 { 663 char *expanded, *ret, cwd[PATH_MAX]; 664 665 if (strcasecmp(path, "none") == 0) 666 return xstrdup("none"); 667 expanded = tilde_expand_filename(path, getuid()); 668 if (path_absolute(expanded)) 669 return expanded; 670 if (getcwd(cwd, sizeof(cwd)) == NULL) 671 fatal("%s: getcwd: %s", __func__, strerror(errno)); 672 xasprintf(&ret, "%s/%s", cwd, expanded); 673 free(expanded); 674 return ret; 675 } 676 677 static void 678 add_listen_addr(ServerOptions *options, const char *addr, 679 const char *rdomain, int port) 680 { 681 u_int i; 682 683 if (port > 0) 684 add_one_listen_addr(options, addr, rdomain, port); 685 else { 686 for (i = 0; i < options->num_ports; i++) { 687 add_one_listen_addr(options, addr, rdomain, 688 options->ports[i]); 689 } 690 } 691 } 692 693 static void 694 add_one_listen_addr(ServerOptions *options, const char *addr, 695 const char *rdomain, int port) 696 { 697 struct addrinfo hints, *ai, *aitop; 698 char strport[NI_MAXSERV]; 699 int gaierr; 700 u_int i; 701 702 /* Find listen_addrs entry for this rdomain */ 703 for (i = 0; i < options->num_listen_addrs; i++) { 704 if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL) 705 break; 706 if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL) 707 continue; 708 if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0) 709 break; 710 } 711 if (i >= options->num_listen_addrs) { 712 /* No entry for this rdomain; allocate one */ 713 if (i >= INT_MAX) 714 fatal("%s: too many listen addresses", __func__); 715 options->listen_addrs = xrecallocarray(options->listen_addrs, 716 options->num_listen_addrs, options->num_listen_addrs + 1, 717 sizeof(*options->listen_addrs)); 718 i = options->num_listen_addrs++; 719 if (rdomain != NULL) 720 options->listen_addrs[i].rdomain = xstrdup(rdomain); 721 } 722 /* options->listen_addrs[i] points to the addresses for this rdomain */ 723 724 memset(&hints, 0, sizeof(hints)); 725 hints.ai_family = options->address_family; 726 hints.ai_socktype = SOCK_STREAM; 727 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 728 snprintf(strport, sizeof strport, "%d", port); 729 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 730 fatal("bad addr or host: %s (%s)", 731 addr ? addr : "<NULL>", 732 ssh_gai_strerror(gaierr)); 733 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 734 ; 735 ai->ai_next = options->listen_addrs[i].addrs; 736 options->listen_addrs[i].addrs = aitop; 737 } 738 739 /* Returns nonzero if the routing domain name is valid */ 740 static int 741 valid_rdomain(const char *name) 742 { 743 const char *errstr; 744 long long num; 745 struct rt_tableinfo info; 746 int mib[6]; 747 size_t miblen = sizeof(mib); 748 749 if (name == NULL) 750 return 1; 751 752 num = strtonum(name, 0, 255, &errstr); 753 if (errstr != NULL) 754 return 0; 755 756 /* Check whether the table actually exists */ 757 memset(mib, 0, sizeof(mib)); 758 mib[0] = CTL_NET; 759 mib[1] = PF_ROUTE; 760 mib[4] = NET_RT_TABLE; 761 mib[5] = (int)num; 762 if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1) 763 return 0; 764 765 return 1; 766 } 767 768 /* 769 * Queue a ListenAddress to be processed once we have all of the Ports 770 * and AddressFamily options. 771 */ 772 static void 773 queue_listen_addr(ServerOptions *options, const char *addr, 774 const char *rdomain, int port) 775 { 776 struct queued_listenaddr *qla; 777 778 options->queued_listen_addrs = xrecallocarray( 779 options->queued_listen_addrs, 780 options->num_queued_listens, options->num_queued_listens + 1, 781 sizeof(*options->queued_listen_addrs)); 782 qla = &options->queued_listen_addrs[options->num_queued_listens++]; 783 qla->addr = xstrdup(addr); 784 qla->port = port; 785 qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain); 786 } 787 788 /* 789 * Process queued (text) ListenAddress entries. 790 */ 791 static void 792 process_queued_listen_addrs(ServerOptions *options) 793 { 794 u_int i; 795 struct queued_listenaddr *qla; 796 797 if (options->num_ports == 0) 798 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 799 if (options->address_family == -1) 800 options->address_family = AF_UNSPEC; 801 802 for (i = 0; i < options->num_queued_listens; i++) { 803 qla = &options->queued_listen_addrs[i]; 804 add_listen_addr(options, qla->addr, qla->rdomain, qla->port); 805 free(qla->addr); 806 free(qla->rdomain); 807 } 808 free(options->queued_listen_addrs); 809 options->queued_listen_addrs = NULL; 810 options->num_queued_listens = 0; 811 } 812 813 /* 814 * Inform channels layer of permitopen options for a single forwarding 815 * direction (local/remote). 816 */ 817 static void 818 process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode, 819 char **opens, u_int num_opens) 820 { 821 u_int i; 822 int port; 823 char *host, *arg, *oarg, ch; 824 int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE; 825 const char *what = lookup_opcode_name(opcode); 826 827 channel_clear_permission(ssh, FORWARD_ADM, where); 828 if (num_opens == 0) 829 return; /* permit any */ 830 831 /* handle keywords: "any" / "none" */ 832 if (num_opens == 1 && strcmp(opens[0], "any") == 0) 833 return; 834 if (num_opens == 1 && strcmp(opens[0], "none") == 0) { 835 channel_disable_admin(ssh, where); 836 return; 837 } 838 /* Otherwise treat it as a list of permitted host:port */ 839 for (i = 0; i < num_opens; i++) { 840 oarg = arg = xstrdup(opens[i]); 841 ch = '\0'; 842 host = hpdelim2(&arg, &ch); 843 if (host == NULL || ch == '/') 844 fatal("%s: missing host in %s", __func__, what); 845 host = cleanhostname(host); 846 if (arg == NULL || ((port = permitopen_port(arg)) < 0)) 847 fatal("%s: bad port number in %s", __func__, what); 848 /* Send it to channels layer */ 849 channel_add_permission(ssh, FORWARD_ADM, 850 where, host, port); 851 free(oarg); 852 } 853 } 854 855 /* 856 * Inform channels layer of permitopen options from configuration. 857 */ 858 void 859 process_permitopen(struct ssh *ssh, ServerOptions *options) 860 { 861 process_permitopen_list(ssh, sPermitOpen, 862 options->permitted_opens, options->num_permitted_opens); 863 process_permitopen_list(ssh, sPermitListen, 864 options->permitted_listens, 865 options->num_permitted_listens); 866 } 867 868 struct connection_info * 869 get_connection_info(struct ssh *ssh, int populate, int use_dns) 870 { 871 static struct connection_info ci; 872 873 if (ssh == NULL || !populate) 874 return &ci; 875 ci.host = auth_get_canonical_hostname(ssh, use_dns); 876 ci.address = ssh_remote_ipaddr(ssh); 877 ci.laddress = ssh_local_ipaddr(ssh); 878 ci.lport = ssh_local_port(ssh); 879 ci.rdomain = ssh_packet_rdomain_in(ssh); 880 return &ci; 881 } 882 883 /* 884 * The strategy for the Match blocks is that the config file is parsed twice. 885 * 886 * The first time is at startup. activep is initialized to 1 and the 887 * directives in the global context are processed and acted on. Hitting a 888 * Match directive unsets activep and the directives inside the block are 889 * checked for syntax only. 890 * 891 * The second time is after a connection has been established but before 892 * authentication. activep is initialized to 2 and global config directives 893 * are ignored since they have already been processed. If the criteria in a 894 * Match block is met, activep is set and the subsequent directives 895 * processed and actioned until EOF or another Match block unsets it. Any 896 * options set are copied into the main server config. 897 * 898 * Potential additions/improvements: 899 * - Add Match support for pre-kex directives, eg. Ciphers. 900 * 901 * - Add a Tag directive (idea from David Leonard) ala pf, eg: 902 * Match Address 192.168.0.* 903 * Tag trusted 904 * Match Group wheel 905 * Tag trusted 906 * Match Tag trusted 907 * AllowTcpForwarding yes 908 * GatewayPorts clientspecified 909 * [...] 910 * 911 * - Add a PermittedChannelRequests directive 912 * Match Group shell 913 * PermittedChannelRequests session,forwarded-tcpip 914 */ 915 916 static int 917 match_cfg_line_group(const char *grps, int line, const char *user) 918 { 919 int result = 0; 920 struct passwd *pw; 921 922 if (user == NULL) 923 goto out; 924 925 if ((pw = getpwnam(user)) == NULL) { 926 debug("Can't match group at line %d because user %.100s does " 927 "not exist", line, user); 928 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 929 debug("Can't Match group because user %.100s not in any group " 930 "at line %d", user, line); 931 } else if (ga_match_pattern_list(grps) != 1) { 932 debug("user %.100s does not match group list %.100s at line %d", 933 user, grps, line); 934 } else { 935 debug("user %.100s matched group list %.100s at line %d", user, 936 grps, line); 937 result = 1; 938 } 939 out: 940 ga_free(); 941 return result; 942 } 943 944 static void 945 match_test_missing_fatal(const char *criteria, const char *attrib) 946 { 947 fatal("'Match %s' in configuration but '%s' not in connection " 948 "test specification.", criteria, attrib); 949 } 950 951 /* 952 * All of the attributes on a single Match line are ANDed together, so we need 953 * to check every attribute and set the result to zero if any attribute does 954 * not match. 955 */ 956 static int 957 match_cfg_line(char **condition, int line, struct connection_info *ci) 958 { 959 int result = 1, attributes = 0, port; 960 char *arg, *attrib, *cp = *condition; 961 962 if (ci == NULL) 963 debug3("checking syntax for 'Match %s'", cp); 964 else 965 debug3("checking match for '%s' user %s host %s addr %s " 966 "laddr %s lport %d", cp, ci->user ? ci->user : "(null)", 967 ci->host ? ci->host : "(null)", 968 ci->address ? ci->address : "(null)", 969 ci->laddress ? ci->laddress : "(null)", ci->lport); 970 971 while ((attrib = strdelim(&cp)) && *attrib != '\0') { 972 attributes++; 973 if (strcasecmp(attrib, "all") == 0) { 974 if (attributes != 1 || 975 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { 976 error("'all' cannot be combined with other " 977 "Match attributes"); 978 return -1; 979 } 980 *condition = cp; 981 return 1; 982 } 983 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 984 error("Missing Match criteria for %s", attrib); 985 return -1; 986 } 987 if (strcasecmp(attrib, "user") == 0) { 988 if (ci == NULL || (ci->test && ci->user == NULL)) { 989 result = 0; 990 continue; 991 } 992 if (ci->user == NULL) 993 match_test_missing_fatal("User", "user"); 994 if (match_usergroup_pattern_list(ci->user, arg) != 1) 995 result = 0; 996 else 997 debug("user %.100s matched 'User %.100s' at " 998 "line %d", ci->user, arg, line); 999 } else if (strcasecmp(attrib, "group") == 0) { 1000 if (ci == NULL || (ci->test && ci->user == NULL)) { 1001 result = 0; 1002 continue; 1003 } 1004 if (ci->user == NULL) 1005 match_test_missing_fatal("Group", "user"); 1006 switch (match_cfg_line_group(arg, line, ci->user)) { 1007 case -1: 1008 return -1; 1009 case 0: 1010 result = 0; 1011 } 1012 } else if (strcasecmp(attrib, "host") == 0) { 1013 if (ci == NULL || (ci->test && ci->host == NULL)) { 1014 result = 0; 1015 continue; 1016 } 1017 if (ci->host == NULL) 1018 match_test_missing_fatal("Host", "host"); 1019 if (match_hostname(ci->host, arg) != 1) 1020 result = 0; 1021 else 1022 debug("connection from %.100s matched 'Host " 1023 "%.100s' at line %d", ci->host, arg, line); 1024 } else if (strcasecmp(attrib, "address") == 0) { 1025 if (ci == NULL || (ci->test && ci->address == NULL)) { 1026 result = 0; 1027 continue; 1028 } 1029 if (ci->address == NULL) 1030 match_test_missing_fatal("Address", "addr"); 1031 switch (addr_match_list(ci->address, arg)) { 1032 case 1: 1033 debug("connection from %.100s matched 'Address " 1034 "%.100s' at line %d", ci->address, arg, line); 1035 break; 1036 case 0: 1037 case -1: 1038 result = 0; 1039 break; 1040 case -2: 1041 return -1; 1042 } 1043 } else if (strcasecmp(attrib, "localaddress") == 0){ 1044 if (ci == NULL || (ci->test && ci->laddress == NULL)) { 1045 result = 0; 1046 continue; 1047 } 1048 if (ci->laddress == NULL) 1049 match_test_missing_fatal("LocalAddress", 1050 "laddr"); 1051 switch (addr_match_list(ci->laddress, arg)) { 1052 case 1: 1053 debug("connection from %.100s matched " 1054 "'LocalAddress %.100s' at line %d", 1055 ci->laddress, arg, line); 1056 break; 1057 case 0: 1058 case -1: 1059 result = 0; 1060 break; 1061 case -2: 1062 return -1; 1063 } 1064 } else if (strcasecmp(attrib, "localport") == 0) { 1065 if ((port = a2port(arg)) == -1) { 1066 error("Invalid LocalPort '%s' on Match line", 1067 arg); 1068 return -1; 1069 } 1070 if (ci == NULL || (ci->test && ci->lport == -1)) { 1071 result = 0; 1072 continue; 1073 } 1074 if (ci->lport == 0) 1075 match_test_missing_fatal("LocalPort", "lport"); 1076 /* TODO support port lists */ 1077 if (port == ci->lport) 1078 debug("connection from %.100s matched " 1079 "'LocalPort %d' at line %d", 1080 ci->laddress, port, line); 1081 else 1082 result = 0; 1083 } else if (strcasecmp(attrib, "rdomain") == 0) { 1084 if (ci == NULL || (ci->test && ci->rdomain == NULL)) { 1085 result = 0; 1086 continue; 1087 } 1088 if (ci->rdomain == NULL) 1089 match_test_missing_fatal("RDomain", "rdomain"); 1090 if (match_pattern_list(ci->rdomain, arg, 0) != 1) 1091 result = 0; 1092 else 1093 debug("user %.100s matched 'RDomain %.100s' at " 1094 "line %d", ci->rdomain, arg, line); 1095 } else { 1096 error("Unsupported Match attribute %s", attrib); 1097 return -1; 1098 } 1099 } 1100 if (attributes == 0) { 1101 error("One or more attributes required for Match"); 1102 return -1; 1103 } 1104 if (ci != NULL) 1105 debug3("match %sfound", result ? "" : "not "); 1106 *condition = cp; 1107 return result; 1108 } 1109 1110 #define WHITESPACE " \t\r\n" 1111 1112 /* Multistate option parsing */ 1113 struct multistate { 1114 char *key; 1115 int value; 1116 }; 1117 static const struct multistate multistate_flag[] = { 1118 { "yes", 1 }, 1119 { "no", 0 }, 1120 { NULL, -1 } 1121 }; 1122 static const struct multistate multistate_addressfamily[] = { 1123 { "inet", AF_INET }, 1124 { "inet6", AF_INET6 }, 1125 { "any", AF_UNSPEC }, 1126 { NULL, -1 } 1127 }; 1128 static const struct multistate multistate_permitrootlogin[] = { 1129 { "without-password", PERMIT_NO_PASSWD }, 1130 { "prohibit-password", PERMIT_NO_PASSWD }, 1131 { "forced-commands-only", PERMIT_FORCED_ONLY }, 1132 { "yes", PERMIT_YES }, 1133 { "no", PERMIT_NO }, 1134 { NULL, -1 } 1135 }; 1136 static const struct multistate multistate_compression[] = { 1137 { "yes", COMP_DELAYED }, 1138 { "delayed", COMP_DELAYED }, 1139 { "no", COMP_NONE }, 1140 { NULL, -1 } 1141 }; 1142 static const struct multistate multistate_gatewayports[] = { 1143 { "clientspecified", 2 }, 1144 { "yes", 1 }, 1145 { "no", 0 }, 1146 { NULL, -1 } 1147 }; 1148 static const struct multistate multistate_tcpfwd[] = { 1149 { "yes", FORWARD_ALLOW }, 1150 { "all", FORWARD_ALLOW }, 1151 { "no", FORWARD_DENY }, 1152 { "remote", FORWARD_REMOTE }, 1153 { "local", FORWARD_LOCAL }, 1154 { NULL, -1 } 1155 }; 1156 1157 int 1158 process_server_config_line(ServerOptions *options, char *line, 1159 const char *filename, int linenum, int *activep, 1160 struct connection_info *connectinfo) 1161 { 1162 char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; 1163 int cmdline = 0, *intptr, value, value2, n, port; 1164 SyslogFacility *log_facility_ptr; 1165 LogLevel *log_level_ptr; 1166 ServerOpCodes opcode; 1167 u_int i, *uintptr, uvalue, flags = 0; 1168 size_t len; 1169 long long val64; 1170 const struct multistate *multistate_ptr; 1171 const char *errstr; 1172 1173 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ 1174 if ((len = strlen(line)) == 0) 1175 return 0; 1176 for (len--; len > 0; len--) { 1177 if (strchr(WHITESPACE "\f", line[len]) == NULL) 1178 break; 1179 line[len] = '\0'; 1180 } 1181 1182 cp = line; 1183 if ((arg = strdelim(&cp)) == NULL) 1184 return 0; 1185 /* Ignore leading whitespace */ 1186 if (*arg == '\0') 1187 arg = strdelim(&cp); 1188 if (!arg || !*arg || *arg == '#') 1189 return 0; 1190 intptr = NULL; 1191 charptr = NULL; 1192 opcode = parse_token(arg, filename, linenum, &flags); 1193 1194 if (activep == NULL) { /* We are processing a command line directive */ 1195 cmdline = 1; 1196 activep = &cmdline; 1197 } 1198 if (*activep && opcode != sMatch) 1199 debug3("%s:%d setting %s %s", filename, linenum, arg, cp); 1200 if (*activep == 0 && !(flags & SSHCFG_MATCH)) { 1201 if (connectinfo == NULL) { 1202 fatal("%s line %d: Directive '%s' is not allowed " 1203 "within a Match block", filename, linenum, arg); 1204 } else { /* this is a directive we have already processed */ 1205 while (arg) 1206 arg = strdelim(&cp); 1207 return 0; 1208 } 1209 } 1210 1211 switch (opcode) { 1212 case sBadOption: 1213 return -1; 1214 case sPort: 1215 /* ignore ports from configfile if cmdline specifies ports */ 1216 if (options->ports_from_cmdline) 1217 return 0; 1218 if (options->num_ports >= MAX_PORTS) 1219 fatal("%s line %d: too many ports.", 1220 filename, linenum); 1221 arg = strdelim(&cp); 1222 if (!arg || *arg == '\0') 1223 fatal("%s line %d: missing port number.", 1224 filename, linenum); 1225 options->ports[options->num_ports++] = a2port(arg); 1226 if (options->ports[options->num_ports-1] <= 0) 1227 fatal("%s line %d: Badly formatted port number.", 1228 filename, linenum); 1229 break; 1230 1231 case sLoginGraceTime: 1232 intptr = &options->login_grace_time; 1233 parse_time: 1234 arg = strdelim(&cp); 1235 if (!arg || *arg == '\0') 1236 fatal("%s line %d: missing time value.", 1237 filename, linenum); 1238 if ((value = convtime(arg)) == -1) 1239 fatal("%s line %d: invalid time value.", 1240 filename, linenum); 1241 if (*activep && *intptr == -1) 1242 *intptr = value; 1243 break; 1244 1245 case sListenAddress: 1246 arg = strdelim(&cp); 1247 if (arg == NULL || *arg == '\0') 1248 fatal("%s line %d: missing address", 1249 filename, linenum); 1250 /* check for bare IPv6 address: no "[]" and 2 or more ":" */ 1251 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL 1252 && strchr(p+1, ':') != NULL) { 1253 port = 0; 1254 p = arg; 1255 } else { 1256 arg2 = NULL; 1257 ch = '\0'; 1258 p = hpdelim2(&arg, &ch); 1259 if (p == NULL || ch == '/') 1260 fatal("%s line %d: bad address:port usage", 1261 filename, linenum); 1262 p = cleanhostname(p); 1263 if (arg == NULL) 1264 port = 0; 1265 else if ((port = a2port(arg)) <= 0) 1266 fatal("%s line %d: bad port number", 1267 filename, linenum); 1268 } 1269 /* Optional routing table */ 1270 arg2 = NULL; 1271 if ((arg = strdelim(&cp)) != NULL) { 1272 if (strcmp(arg, "rdomain") != 0 || 1273 (arg2 = strdelim(&cp)) == NULL) 1274 fatal("%s line %d: bad ListenAddress syntax", 1275 filename, linenum); 1276 if (!valid_rdomain(arg2)) 1277 fatal("%s line %d: bad routing domain", 1278 filename, linenum); 1279 } 1280 1281 queue_listen_addr(options, p, arg2, port); 1282 1283 break; 1284 1285 case sAddressFamily: 1286 intptr = &options->address_family; 1287 multistate_ptr = multistate_addressfamily; 1288 parse_multistate: 1289 arg = strdelim(&cp); 1290 if (!arg || *arg == '\0') 1291 fatal("%s line %d: missing argument.", 1292 filename, linenum); 1293 value = -1; 1294 for (i = 0; multistate_ptr[i].key != NULL; i++) { 1295 if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 1296 value = multistate_ptr[i].value; 1297 break; 1298 } 1299 } 1300 if (value == -1) 1301 fatal("%s line %d: unsupported option \"%s\".", 1302 filename, linenum, arg); 1303 if (*activep && *intptr == -1) 1304 *intptr = value; 1305 break; 1306 1307 case sHostKeyFile: 1308 arg = strdelim(&cp); 1309 if (!arg || *arg == '\0') 1310 fatal("%s line %d: missing file name.", 1311 filename, linenum); 1312 if (*activep) { 1313 servconf_add_hostkey(filename, linenum, 1314 options, arg, 1); 1315 } 1316 break; 1317 1318 case sHostKeyAgent: 1319 charptr = &options->host_key_agent; 1320 arg = strdelim(&cp); 1321 if (!arg || *arg == '\0') 1322 fatal("%s line %d: missing socket name.", 1323 filename, linenum); 1324 if (*activep && *charptr == NULL) 1325 *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ? 1326 xstrdup(arg) : derelativise_path(arg); 1327 break; 1328 1329 case sHostCertificate: 1330 arg = strdelim(&cp); 1331 if (!arg || *arg == '\0') 1332 fatal("%s line %d: missing file name.", 1333 filename, linenum); 1334 if (*activep) 1335 servconf_add_hostcert(filename, linenum, options, arg); 1336 break; 1337 1338 case sPidFile: 1339 charptr = &options->pid_file; 1340 parse_filename: 1341 arg = strdelim(&cp); 1342 if (!arg || *arg == '\0') 1343 fatal("%s line %d: missing file name.", 1344 filename, linenum); 1345 if (*activep && *charptr == NULL) { 1346 *charptr = derelativise_path(arg); 1347 /* increase optional counter */ 1348 if (intptr != NULL) 1349 *intptr = *intptr + 1; 1350 } 1351 break; 1352 1353 case sPermitRootLogin: 1354 intptr = &options->permit_root_login; 1355 multistate_ptr = multistate_permitrootlogin; 1356 goto parse_multistate; 1357 1358 case sIgnoreRhosts: 1359 intptr = &options->ignore_rhosts; 1360 parse_flag: 1361 multistate_ptr = multistate_flag; 1362 goto parse_multistate; 1363 1364 case sIgnoreUserKnownHosts: 1365 intptr = &options->ignore_user_known_hosts; 1366 goto parse_flag; 1367 1368 case sHostbasedAuthentication: 1369 intptr = &options->hostbased_authentication; 1370 goto parse_flag; 1371 1372 case sHostbasedUsesNameFromPacketOnly: 1373 intptr = &options->hostbased_uses_name_from_packet_only; 1374 goto parse_flag; 1375 1376 case sHostbasedAcceptedKeyTypes: 1377 charptr = &options->hostbased_key_types; 1378 parse_keytypes: 1379 arg = strdelim(&cp); 1380 if (!arg || *arg == '\0') 1381 fatal("%s line %d: Missing argument.", 1382 filename, linenum); 1383 if (*arg != '-' && 1384 !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) 1385 fatal("%s line %d: Bad key types '%s'.", 1386 filename, linenum, arg ? arg : "<NONE>"); 1387 if (*activep && *charptr == NULL) 1388 *charptr = xstrdup(arg); 1389 break; 1390 1391 case sHostKeyAlgorithms: 1392 charptr = &options->hostkeyalgorithms; 1393 goto parse_keytypes; 1394 1395 case sCASignatureAlgorithms: 1396 charptr = &options->ca_sign_algorithms; 1397 goto parse_keytypes; 1398 1399 case sPubkeyAuthentication: 1400 intptr = &options->pubkey_authentication; 1401 goto parse_flag; 1402 1403 case sPubkeyAcceptedKeyTypes: 1404 charptr = &options->pubkey_key_types; 1405 goto parse_keytypes; 1406 1407 case sKerberosAuthentication: 1408 intptr = &options->kerberos_authentication; 1409 goto parse_flag; 1410 1411 case sKerberosOrLocalPasswd: 1412 intptr = &options->kerberos_or_local_passwd; 1413 goto parse_flag; 1414 1415 case sKerberosTicketCleanup: 1416 intptr = &options->kerberos_ticket_cleanup; 1417 goto parse_flag; 1418 1419 case sKerberosGetAFSToken: 1420 intptr = &options->kerberos_get_afs_token; 1421 goto parse_flag; 1422 1423 case sGssAuthentication: 1424 intptr = &options->gss_authentication; 1425 goto parse_flag; 1426 1427 case sGssCleanupCreds: 1428 intptr = &options->gss_cleanup_creds; 1429 goto parse_flag; 1430 1431 case sGssStrictAcceptor: 1432 intptr = &options->gss_strict_acceptor; 1433 goto parse_flag; 1434 1435 case sPasswordAuthentication: 1436 intptr = &options->password_authentication; 1437 goto parse_flag; 1438 1439 case sKbdInteractiveAuthentication: 1440 intptr = &options->kbd_interactive_authentication; 1441 goto parse_flag; 1442 1443 case sChallengeResponseAuthentication: 1444 intptr = &options->challenge_response_authentication; 1445 goto parse_flag; 1446 1447 case sPrintMotd: 1448 intptr = &options->print_motd; 1449 goto parse_flag; 1450 1451 case sPrintLastLog: 1452 intptr = &options->print_lastlog; 1453 goto parse_flag; 1454 1455 case sX11Forwarding: 1456 intptr = &options->x11_forwarding; 1457 goto parse_flag; 1458 1459 case sX11DisplayOffset: 1460 intptr = &options->x11_display_offset; 1461 parse_int: 1462 arg = strdelim(&cp); 1463 if ((errstr = atoi_err(arg, &value)) != NULL) 1464 fatal("%s line %d: integer value %s.", 1465 filename, linenum, errstr); 1466 if (*activep && *intptr == -1) 1467 *intptr = value; 1468 break; 1469 1470 case sX11UseLocalhost: 1471 intptr = &options->x11_use_localhost; 1472 goto parse_flag; 1473 1474 case sXAuthLocation: 1475 charptr = &options->xauth_location; 1476 goto parse_filename; 1477 1478 case sPermitTTY: 1479 intptr = &options->permit_tty; 1480 goto parse_flag; 1481 1482 case sPermitUserRC: 1483 intptr = &options->permit_user_rc; 1484 goto parse_flag; 1485 1486 case sStrictModes: 1487 intptr = &options->strict_modes; 1488 goto parse_flag; 1489 1490 case sTCPKeepAlive: 1491 intptr = &options->tcp_keep_alive; 1492 goto parse_flag; 1493 1494 case sEmptyPasswd: 1495 intptr = &options->permit_empty_passwd; 1496 goto parse_flag; 1497 1498 case sPermitUserEnvironment: 1499 intptr = &options->permit_user_env; 1500 charptr = &options->permit_user_env_whitelist; 1501 arg = strdelim(&cp); 1502 if (!arg || *arg == '\0') 1503 fatal("%s line %d: missing argument.", 1504 filename, linenum); 1505 value = 0; 1506 p = NULL; 1507 if (strcmp(arg, "yes") == 0) 1508 value = 1; 1509 else if (strcmp(arg, "no") == 0) 1510 value = 0; 1511 else { 1512 /* Pattern-list specified */ 1513 value = 1; 1514 p = xstrdup(arg); 1515 } 1516 if (*activep && *intptr == -1) { 1517 *intptr = value; 1518 *charptr = p; 1519 p = NULL; 1520 } 1521 free(p); 1522 break; 1523 1524 case sCompression: 1525 intptr = &options->compression; 1526 multistate_ptr = multistate_compression; 1527 goto parse_multistate; 1528 1529 case sRekeyLimit: 1530 arg = strdelim(&cp); 1531 if (!arg || *arg == '\0') 1532 fatal("%.200s line %d: Missing argument.", filename, 1533 linenum); 1534 if (strcmp(arg, "default") == 0) { 1535 val64 = 0; 1536 } else { 1537 if (scan_scaled(arg, &val64) == -1) 1538 fatal("%.200s line %d: Bad number '%s': %s", 1539 filename, linenum, arg, strerror(errno)); 1540 if (val64 != 0 && val64 < 16) 1541 fatal("%.200s line %d: RekeyLimit too small", 1542 filename, linenum); 1543 } 1544 if (*activep && options->rekey_limit == -1) 1545 options->rekey_limit = val64; 1546 if (cp != NULL) { /* optional rekey interval present */ 1547 if (strcmp(cp, "none") == 0) { 1548 (void)strdelim(&cp); /* discard */ 1549 break; 1550 } 1551 intptr = &options->rekey_interval; 1552 goto parse_time; 1553 } 1554 break; 1555 1556 case sGatewayPorts: 1557 intptr = &options->fwd_opts.gateway_ports; 1558 multistate_ptr = multistate_gatewayports; 1559 goto parse_multistate; 1560 1561 case sUseDNS: 1562 intptr = &options->use_dns; 1563 goto parse_flag; 1564 1565 case sLogFacility: 1566 log_facility_ptr = &options->log_facility; 1567 arg = strdelim(&cp); 1568 value = log_facility_number(arg); 1569 if (value == SYSLOG_FACILITY_NOT_SET) 1570 fatal("%.200s line %d: unsupported log facility '%s'", 1571 filename, linenum, arg ? arg : "<NONE>"); 1572 if (*log_facility_ptr == -1) 1573 *log_facility_ptr = (SyslogFacility) value; 1574 break; 1575 1576 case sLogLevel: 1577 log_level_ptr = &options->log_level; 1578 arg = strdelim(&cp); 1579 value = log_level_number(arg); 1580 if (value == SYSLOG_LEVEL_NOT_SET) 1581 fatal("%.200s line %d: unsupported log level '%s'", 1582 filename, linenum, arg ? arg : "<NONE>"); 1583 if (*activep && *log_level_ptr == -1) 1584 *log_level_ptr = (LogLevel) value; 1585 break; 1586 1587 case sAllowTcpForwarding: 1588 intptr = &options->allow_tcp_forwarding; 1589 multistate_ptr = multistate_tcpfwd; 1590 goto parse_multistate; 1591 1592 case sAllowStreamLocalForwarding: 1593 intptr = &options->allow_streamlocal_forwarding; 1594 multistate_ptr = multistate_tcpfwd; 1595 goto parse_multistate; 1596 1597 case sAllowAgentForwarding: 1598 intptr = &options->allow_agent_forwarding; 1599 goto parse_flag; 1600 1601 case sDisableForwarding: 1602 intptr = &options->disable_forwarding; 1603 goto parse_flag; 1604 1605 case sAllowUsers: 1606 while ((arg = strdelim(&cp)) && *arg != '\0') { 1607 if (match_user(NULL, NULL, NULL, arg) == -1) 1608 fatal("%s line %d: invalid AllowUsers pattern: " 1609 "\"%.100s\"", filename, linenum, arg); 1610 if (!*activep) 1611 continue; 1612 array_append(filename, linenum, "AllowUsers", 1613 &options->allow_users, &options->num_allow_users, 1614 arg); 1615 } 1616 break; 1617 1618 case sDenyUsers: 1619 while ((arg = strdelim(&cp)) && *arg != '\0') { 1620 if (match_user(NULL, NULL, NULL, arg) == -1) 1621 fatal("%s line %d: invalid DenyUsers pattern: " 1622 "\"%.100s\"", filename, linenum, arg); 1623 if (!*activep) 1624 continue; 1625 array_append(filename, linenum, "DenyUsers", 1626 &options->deny_users, &options->num_deny_users, 1627 arg); 1628 } 1629 break; 1630 1631 case sAllowGroups: 1632 while ((arg = strdelim(&cp)) && *arg != '\0') { 1633 if (!*activep) 1634 continue; 1635 array_append(filename, linenum, "AllowGroups", 1636 &options->allow_groups, &options->num_allow_groups, 1637 arg); 1638 } 1639 break; 1640 1641 case sDenyGroups: 1642 while ((arg = strdelim(&cp)) && *arg != '\0') { 1643 if (!*activep) 1644 continue; 1645 array_append(filename, linenum, "DenyGroups", 1646 &options->deny_groups, &options->num_deny_groups, 1647 arg); 1648 } 1649 break; 1650 1651 case sCiphers: 1652 arg = strdelim(&cp); 1653 if (!arg || *arg == '\0') 1654 fatal("%s line %d: Missing argument.", filename, linenum); 1655 if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg)) 1656 fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 1657 filename, linenum, arg ? arg : "<NONE>"); 1658 if (options->ciphers == NULL) 1659 options->ciphers = xstrdup(arg); 1660 break; 1661 1662 case sMacs: 1663 arg = strdelim(&cp); 1664 if (!arg || *arg == '\0') 1665 fatal("%s line %d: Missing argument.", filename, linenum); 1666 if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg)) 1667 fatal("%s line %d: Bad SSH2 mac spec '%s'.", 1668 filename, linenum, arg ? arg : "<NONE>"); 1669 if (options->macs == NULL) 1670 options->macs = xstrdup(arg); 1671 break; 1672 1673 case sKexAlgorithms: 1674 arg = strdelim(&cp); 1675 if (!arg || *arg == '\0') 1676 fatal("%s line %d: Missing argument.", 1677 filename, linenum); 1678 if (*arg != '-' && 1679 !kex_names_valid(*arg == '+' ? arg + 1 : arg)) 1680 fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", 1681 filename, linenum, arg ? arg : "<NONE>"); 1682 if (options->kex_algorithms == NULL) 1683 options->kex_algorithms = xstrdup(arg); 1684 break; 1685 1686 case sSubsystem: 1687 if (options->num_subsystems >= MAX_SUBSYSTEMS) { 1688 fatal("%s line %d: too many subsystems defined.", 1689 filename, linenum); 1690 } 1691 arg = strdelim(&cp); 1692 if (!arg || *arg == '\0') 1693 fatal("%s line %d: Missing subsystem name.", 1694 filename, linenum); 1695 if (!*activep) { 1696 arg = strdelim(&cp); 1697 break; 1698 } 1699 for (i = 0; i < options->num_subsystems; i++) 1700 if (strcmp(arg, options->subsystem_name[i]) == 0) 1701 fatal("%s line %d: Subsystem '%s' already defined.", 1702 filename, linenum, arg); 1703 options->subsystem_name[options->num_subsystems] = xstrdup(arg); 1704 arg = strdelim(&cp); 1705 if (!arg || *arg == '\0') 1706 fatal("%s line %d: Missing subsystem command.", 1707 filename, linenum); 1708 options->subsystem_command[options->num_subsystems] = xstrdup(arg); 1709 1710 /* Collect arguments (separate to executable) */ 1711 p = xstrdup(arg); 1712 len = strlen(p) + 1; 1713 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { 1714 len += 1 + strlen(arg); 1715 p = xreallocarray(p, 1, len); 1716 strlcat(p, " ", len); 1717 strlcat(p, arg, len); 1718 } 1719 options->subsystem_args[options->num_subsystems] = p; 1720 options->num_subsystems++; 1721 break; 1722 1723 case sMaxStartups: 1724 arg = strdelim(&cp); 1725 if (!arg || *arg == '\0') 1726 fatal("%s line %d: Missing MaxStartups spec.", 1727 filename, linenum); 1728 if ((n = sscanf(arg, "%d:%d:%d", 1729 &options->max_startups_begin, 1730 &options->max_startups_rate, 1731 &options->max_startups)) == 3) { 1732 if (options->max_startups_begin > 1733 options->max_startups || 1734 options->max_startups_rate > 100 || 1735 options->max_startups_rate < 1) 1736 fatal("%s line %d: Illegal MaxStartups spec.", 1737 filename, linenum); 1738 } else if (n != 1) 1739 fatal("%s line %d: Illegal MaxStartups spec.", 1740 filename, linenum); 1741 else 1742 options->max_startups = options->max_startups_begin; 1743 break; 1744 1745 case sMaxAuthTries: 1746 intptr = &options->max_authtries; 1747 goto parse_int; 1748 1749 case sMaxSessions: 1750 intptr = &options->max_sessions; 1751 goto parse_int; 1752 1753 case sBanner: 1754 charptr = &options->banner; 1755 goto parse_filename; 1756 1757 /* 1758 * These options can contain %X options expanded at 1759 * connect time, so that you can specify paths like: 1760 * 1761 * AuthorizedKeysFile /etc/ssh_keys/%u 1762 */ 1763 case sAuthorizedKeysFile: 1764 if (*activep && options->num_authkeys_files == 0) { 1765 while ((arg = strdelim(&cp)) && *arg != '\0') { 1766 arg = tilde_expand_filename(arg, getuid()); 1767 array_append(filename, linenum, 1768 "AuthorizedKeysFile", 1769 &options->authorized_keys_files, 1770 &options->num_authkeys_files, arg); 1771 free(arg); 1772 } 1773 } 1774 return 0; 1775 1776 case sAuthorizedPrincipalsFile: 1777 charptr = &options->authorized_principals_file; 1778 arg = strdelim(&cp); 1779 if (!arg || *arg == '\0') 1780 fatal("%s line %d: missing file name.", 1781 filename, linenum); 1782 if (*activep && *charptr == NULL) { 1783 *charptr = tilde_expand_filename(arg, getuid()); 1784 /* increase optional counter */ 1785 if (intptr != NULL) 1786 *intptr = *intptr + 1; 1787 } 1788 break; 1789 1790 case sClientAliveInterval: 1791 intptr = &options->client_alive_interval; 1792 goto parse_time; 1793 1794 case sClientAliveCountMax: 1795 intptr = &options->client_alive_count_max; 1796 goto parse_int; 1797 1798 case sAcceptEnv: 1799 while ((arg = strdelim(&cp)) && *arg != '\0') { 1800 if (strchr(arg, '=') != NULL) 1801 fatal("%s line %d: Invalid environment name.", 1802 filename, linenum); 1803 if (!*activep) 1804 continue; 1805 array_append(filename, linenum, "AcceptEnv", 1806 &options->accept_env, &options->num_accept_env, 1807 arg); 1808 } 1809 break; 1810 1811 case sSetEnv: 1812 uvalue = options->num_setenv; 1813 while ((arg = strdelimw(&cp)) && *arg != '\0') { 1814 if (strchr(arg, '=') == NULL) 1815 fatal("%s line %d: Invalid environment.", 1816 filename, linenum); 1817 if (!*activep || uvalue != 0) 1818 continue; 1819 array_append(filename, linenum, "SetEnv", 1820 &options->setenv, &options->num_setenv, arg); 1821 } 1822 break; 1823 1824 case sPermitTunnel: 1825 intptr = &options->permit_tun; 1826 arg = strdelim(&cp); 1827 if (!arg || *arg == '\0') 1828 fatal("%s line %d: Missing yes/point-to-point/" 1829 "ethernet/no argument.", filename, linenum); 1830 value = -1; 1831 for (i = 0; tunmode_desc[i].val != -1; i++) 1832 if (strcmp(tunmode_desc[i].text, arg) == 0) { 1833 value = tunmode_desc[i].val; 1834 break; 1835 } 1836 if (value == -1) 1837 fatal("%s line %d: Bad yes/point-to-point/ethernet/" 1838 "no argument: %s", filename, linenum, arg); 1839 if (*activep && *intptr == -1) 1840 *intptr = value; 1841 break; 1842 1843 case sMatch: 1844 if (cmdline) 1845 fatal("Match directive not supported as a command-line " 1846 "option"); 1847 value = match_cfg_line(&cp, linenum, connectinfo); 1848 if (value < 0) 1849 fatal("%s line %d: Bad Match condition", filename, 1850 linenum); 1851 *activep = value; 1852 break; 1853 1854 case sPermitListen: 1855 case sPermitOpen: 1856 if (opcode == sPermitListen) { 1857 uintptr = &options->num_permitted_listens; 1858 chararrayptr = &options->permitted_listens; 1859 } else { 1860 uintptr = &options->num_permitted_opens; 1861 chararrayptr = &options->permitted_opens; 1862 } 1863 arg = strdelim(&cp); 1864 if (!arg || *arg == '\0') 1865 fatal("%s line %d: missing %s specification", 1866 filename, linenum, lookup_opcode_name(opcode)); 1867 uvalue = *uintptr; /* modified later */ 1868 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { 1869 if (*activep && uvalue == 0) { 1870 *uintptr = 1; 1871 *chararrayptr = xcalloc(1, 1872 sizeof(**chararrayptr)); 1873 (*chararrayptr)[0] = xstrdup(arg); 1874 } 1875 break; 1876 } 1877 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { 1878 if (opcode == sPermitListen && 1879 strchr(arg, ':') == NULL) { 1880 /* 1881 * Allow bare port number for PermitListen 1882 * to indicate a wildcard listen host. 1883 */ 1884 xasprintf(&arg2, "*:%s", arg); 1885 } else { 1886 arg2 = xstrdup(arg); 1887 ch = '\0'; 1888 p = hpdelim2(&arg, &ch); 1889 if (p == NULL || ch == '/') { 1890 fatal("%s line %d: missing host in %s", 1891 filename, linenum, 1892 lookup_opcode_name(opcode)); 1893 } 1894 p = cleanhostname(p); 1895 } 1896 if (arg == NULL || 1897 ((port = permitopen_port(arg)) < 0)) { 1898 fatal("%s line %d: bad port number in %s", 1899 filename, linenum, 1900 lookup_opcode_name(opcode)); 1901 } 1902 if (*activep && uvalue == 0) { 1903 array_append(filename, linenum, 1904 lookup_opcode_name(opcode), 1905 chararrayptr, uintptr, arg2); 1906 } 1907 free(arg2); 1908 } 1909 break; 1910 1911 case sForceCommand: 1912 if (cp == NULL || *cp == '\0') 1913 fatal("%.200s line %d: Missing argument.", filename, 1914 linenum); 1915 len = strspn(cp, WHITESPACE); 1916 if (*activep && options->adm_forced_command == NULL) 1917 options->adm_forced_command = xstrdup(cp + len); 1918 return 0; 1919 1920 case sChrootDirectory: 1921 charptr = &options->chroot_directory; 1922 1923 arg = strdelim(&cp); 1924 if (!arg || *arg == '\0') 1925 fatal("%s line %d: missing file name.", 1926 filename, linenum); 1927 if (*activep && *charptr == NULL) 1928 *charptr = xstrdup(arg); 1929 break; 1930 1931 case sTrustedUserCAKeys: 1932 charptr = &options->trusted_user_ca_keys; 1933 goto parse_filename; 1934 1935 case sRevokedKeys: 1936 charptr = &options->revoked_keys_file; 1937 goto parse_filename; 1938 1939 case sIPQoS: 1940 arg = strdelim(&cp); 1941 if ((value = parse_ipqos(arg)) == -1) 1942 fatal("%s line %d: Bad IPQoS value: %s", 1943 filename, linenum, arg); 1944 arg = strdelim(&cp); 1945 if (arg == NULL) 1946 value2 = value; 1947 else if ((value2 = parse_ipqos(arg)) == -1) 1948 fatal("%s line %d: Bad IPQoS value: %s", 1949 filename, linenum, arg); 1950 if (*activep) { 1951 options->ip_qos_interactive = value; 1952 options->ip_qos_bulk = value2; 1953 } 1954 break; 1955 1956 case sVersionAddendum: 1957 if (cp == NULL || *cp == '\0') 1958 fatal("%.200s line %d: Missing argument.", filename, 1959 linenum); 1960 len = strspn(cp, WHITESPACE); 1961 if (*activep && options->version_addendum == NULL) { 1962 if (strcasecmp(cp + len, "none") == 0) 1963 options->version_addendum = xstrdup(""); 1964 else if (strchr(cp + len, '\r') != NULL) 1965 fatal("%.200s line %d: Invalid argument", 1966 filename, linenum); 1967 else 1968 options->version_addendum = xstrdup(cp + len); 1969 } 1970 return 0; 1971 1972 case sAuthorizedKeysCommand: 1973 if (cp == NULL) 1974 fatal("%.200s line %d: Missing argument.", filename, 1975 linenum); 1976 len = strspn(cp, WHITESPACE); 1977 if (*activep && options->authorized_keys_command == NULL) { 1978 if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) 1979 fatal("%.200s line %d: AuthorizedKeysCommand " 1980 "must be an absolute path", 1981 filename, linenum); 1982 options->authorized_keys_command = xstrdup(cp + len); 1983 } 1984 return 0; 1985 1986 case sAuthorizedKeysCommandUser: 1987 charptr = &options->authorized_keys_command_user; 1988 1989 arg = strdelim(&cp); 1990 if (!arg || *arg == '\0') 1991 fatal("%s line %d: missing AuthorizedKeysCommandUser " 1992 "argument.", filename, linenum); 1993 if (*activep && *charptr == NULL) 1994 *charptr = xstrdup(arg); 1995 break; 1996 1997 case sAuthorizedPrincipalsCommand: 1998 if (cp == NULL) 1999 fatal("%.200s line %d: Missing argument.", filename, 2000 linenum); 2001 len = strspn(cp, WHITESPACE); 2002 if (*activep && 2003 options->authorized_principals_command == NULL) { 2004 if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) 2005 fatal("%.200s line %d: " 2006 "AuthorizedPrincipalsCommand must be " 2007 "an absolute path", filename, linenum); 2008 options->authorized_principals_command = 2009 xstrdup(cp + len); 2010 } 2011 return 0; 2012 2013 case sAuthorizedPrincipalsCommandUser: 2014 charptr = &options->authorized_principals_command_user; 2015 2016 arg = strdelim(&cp); 2017 if (!arg || *arg == '\0') 2018 fatal("%s line %d: missing " 2019 "AuthorizedPrincipalsCommandUser argument.", 2020 filename, linenum); 2021 if (*activep && *charptr == NULL) 2022 *charptr = xstrdup(arg); 2023 break; 2024 2025 case sAuthenticationMethods: 2026 if (options->num_auth_methods == 0) { 2027 value = 0; /* seen "any" pseudo-method */ 2028 value2 = 0; /* successfully parsed any method */ 2029 while ((arg = strdelim(&cp)) && *arg != '\0') { 2030 if (strcmp(arg, "any") == 0) { 2031 if (options->num_auth_methods > 0) { 2032 fatal("%s line %d: \"any\" " 2033 "must appear alone in " 2034 "AuthenticationMethods", 2035 filename, linenum); 2036 } 2037 value = 1; 2038 } else if (value) { 2039 fatal("%s line %d: \"any\" must appear " 2040 "alone in AuthenticationMethods", 2041 filename, linenum); 2042 } else if (auth2_methods_valid(arg, 0) != 0) { 2043 fatal("%s line %d: invalid " 2044 "authentication method list.", 2045 filename, linenum); 2046 } 2047 value2 = 1; 2048 if (!*activep) 2049 continue; 2050 array_append(filename, linenum, 2051 "AuthenticationMethods", 2052 &options->auth_methods, 2053 &options->num_auth_methods, arg); 2054 } 2055 if (value2 == 0) { 2056 fatal("%s line %d: no AuthenticationMethods " 2057 "specified", filename, linenum); 2058 } 2059 } 2060 return 0; 2061 2062 case sStreamLocalBindMask: 2063 arg = strdelim(&cp); 2064 if (!arg || *arg == '\0') 2065 fatal("%s line %d: missing StreamLocalBindMask " 2066 "argument.", filename, linenum); 2067 /* Parse mode in octal format */ 2068 value = strtol(arg, &p, 8); 2069 if (arg == p || value < 0 || value > 0777) 2070 fatal("%s line %d: Bad mask.", filename, linenum); 2071 if (*activep) 2072 options->fwd_opts.streamlocal_bind_mask = (mode_t)value; 2073 break; 2074 2075 case sStreamLocalBindUnlink: 2076 intptr = &options->fwd_opts.streamlocal_bind_unlink; 2077 goto parse_flag; 2078 2079 case sFingerprintHash: 2080 arg = strdelim(&cp); 2081 if (!arg || *arg == '\0') 2082 fatal("%.200s line %d: Missing argument.", 2083 filename, linenum); 2084 if ((value = ssh_digest_alg_by_name(arg)) == -1) 2085 fatal("%.200s line %d: Invalid hash algorithm \"%s\".", 2086 filename, linenum, arg); 2087 if (*activep) 2088 options->fingerprint_hash = value; 2089 break; 2090 2091 case sExposeAuthInfo: 2092 intptr = &options->expose_userauth_info; 2093 goto parse_flag; 2094 2095 case sRDomain: 2096 charptr = &options->routing_domain; 2097 arg = strdelim(&cp); 2098 if (!arg || *arg == '\0') 2099 fatal("%.200s line %d: Missing argument.", 2100 filename, linenum); 2101 if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 && 2102 !valid_rdomain(arg)) 2103 fatal("%s line %d: bad routing domain", 2104 filename, linenum); 2105 if (*activep && *charptr == NULL) 2106 *charptr = xstrdup(arg); 2107 break; 2108 2109 case sDeprecated: 2110 case sIgnore: 2111 case sUnsupported: 2112 do_log2(opcode == sIgnore ? 2113 SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO, 2114 "%s line %d: %s option %s", filename, linenum, 2115 opcode == sUnsupported ? "Unsupported" : "Deprecated", arg); 2116 while (arg) 2117 arg = strdelim(&cp); 2118 break; 2119 2120 default: 2121 fatal("%s line %d: Missing handler for opcode %s (%d)", 2122 filename, linenum, arg, opcode); 2123 } 2124 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') 2125 fatal("%s line %d: garbage at end of line; \"%.200s\".", 2126 filename, linenum, arg); 2127 return 0; 2128 } 2129 2130 /* Reads the server configuration file. */ 2131 2132 void 2133 load_server_config(const char *filename, struct sshbuf *conf) 2134 { 2135 char *line = NULL, *cp; 2136 size_t linesize = 0; 2137 FILE *f; 2138 int r, lineno = 0; 2139 2140 debug2("%s: filename %s", __func__, filename); 2141 if ((f = fopen(filename, "r")) == NULL) { 2142 perror(filename); 2143 exit(1); 2144 } 2145 sshbuf_reset(conf); 2146 while (getline(&line, &linesize, f) != -1) { 2147 lineno++; 2148 /* 2149 * Trim out comments and strip whitespace 2150 * NB - preserve newlines, they are needed to reproduce 2151 * line numbers later for error messages 2152 */ 2153 if ((cp = strchr(line, '#')) != NULL) 2154 memcpy(cp, "\n", 2); 2155 cp = line + strspn(line, " \t\r"); 2156 if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0) 2157 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 2158 } 2159 free(line); 2160 if ((r = sshbuf_put_u8(conf, 0)) != 0) 2161 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 2162 fclose(f); 2163 debug2("%s: done config len = %zu", __func__, sshbuf_len(conf)); 2164 } 2165 2166 void 2167 parse_server_match_config(ServerOptions *options, 2168 struct connection_info *connectinfo) 2169 { 2170 ServerOptions mo; 2171 2172 initialize_server_options(&mo); 2173 parse_server_config(&mo, "reprocess config", cfg, connectinfo); 2174 copy_set_server_options(options, &mo, 0); 2175 } 2176 2177 int parse_server_match_testspec(struct connection_info *ci, char *spec) 2178 { 2179 char *p; 2180 2181 while ((p = strsep(&spec, ",")) && *p != '\0') { 2182 if (strncmp(p, "addr=", 5) == 0) { 2183 ci->address = xstrdup(p + 5); 2184 } else if (strncmp(p, "host=", 5) == 0) { 2185 ci->host = xstrdup(p + 5); 2186 } else if (strncmp(p, "user=", 5) == 0) { 2187 ci->user = xstrdup(p + 5); 2188 } else if (strncmp(p, "laddr=", 6) == 0) { 2189 ci->laddress = xstrdup(p + 6); 2190 } else if (strncmp(p, "rdomain=", 8) == 0) { 2191 ci->rdomain = xstrdup(p + 8); 2192 } else if (strncmp(p, "lport=", 6) == 0) { 2193 ci->lport = a2port(p + 6); 2194 if (ci->lport == -1) { 2195 fprintf(stderr, "Invalid port '%s' in test mode" 2196 " specification %s\n", p+6, p); 2197 return -1; 2198 } 2199 } else { 2200 fprintf(stderr, "Invalid test mode specification %s\n", 2201 p); 2202 return -1; 2203 } 2204 } 2205 return 0; 2206 } 2207 2208 /* 2209 * Copy any supported values that are set. 2210 * 2211 * If the preauth flag is set, we do not bother copying the string or 2212 * array values that are not used pre-authentication, because any that we 2213 * do use must be explicitly sent in mm_getpwnamallow(). 2214 */ 2215 void 2216 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) 2217 { 2218 #define M_CP_INTOPT(n) do {\ 2219 if (src->n != -1) \ 2220 dst->n = src->n; \ 2221 } while (0) 2222 2223 M_CP_INTOPT(password_authentication); 2224 M_CP_INTOPT(gss_authentication); 2225 M_CP_INTOPT(pubkey_authentication); 2226 M_CP_INTOPT(kerberos_authentication); 2227 M_CP_INTOPT(hostbased_authentication); 2228 M_CP_INTOPT(hostbased_uses_name_from_packet_only); 2229 M_CP_INTOPT(kbd_interactive_authentication); 2230 M_CP_INTOPT(permit_root_login); 2231 M_CP_INTOPT(permit_empty_passwd); 2232 2233 M_CP_INTOPT(allow_tcp_forwarding); 2234 M_CP_INTOPT(allow_streamlocal_forwarding); 2235 M_CP_INTOPT(allow_agent_forwarding); 2236 M_CP_INTOPT(disable_forwarding); 2237 M_CP_INTOPT(expose_userauth_info); 2238 M_CP_INTOPT(permit_tun); 2239 M_CP_INTOPT(fwd_opts.gateway_ports); 2240 M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); 2241 M_CP_INTOPT(x11_display_offset); 2242 M_CP_INTOPT(x11_forwarding); 2243 M_CP_INTOPT(x11_use_localhost); 2244 M_CP_INTOPT(permit_tty); 2245 M_CP_INTOPT(permit_user_rc); 2246 M_CP_INTOPT(max_sessions); 2247 M_CP_INTOPT(max_authtries); 2248 M_CP_INTOPT(client_alive_count_max); 2249 M_CP_INTOPT(client_alive_interval); 2250 M_CP_INTOPT(ip_qos_interactive); 2251 M_CP_INTOPT(ip_qos_bulk); 2252 M_CP_INTOPT(rekey_limit); 2253 M_CP_INTOPT(rekey_interval); 2254 M_CP_INTOPT(log_level); 2255 2256 /* 2257 * The bind_mask is a mode_t that may be unsigned, so we can't use 2258 * M_CP_INTOPT - it does a signed comparison that causes compiler 2259 * warnings. 2260 */ 2261 if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) { 2262 dst->fwd_opts.streamlocal_bind_mask = 2263 src->fwd_opts.streamlocal_bind_mask; 2264 } 2265 2266 /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */ 2267 #define M_CP_STROPT(n) do {\ 2268 if (src->n != NULL && dst->n != src->n) { \ 2269 free(dst->n); \ 2270 dst->n = src->n; \ 2271 } \ 2272 } while(0) 2273 #define M_CP_STRARRAYOPT(s, num_s) do {\ 2274 u_int i; \ 2275 if (src->num_s != 0) { \ 2276 for (i = 0; i < dst->num_s; i++) \ 2277 free(dst->s[i]); \ 2278 free(dst->s); \ 2279 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \ 2280 for (i = 0; i < src->num_s; i++) \ 2281 dst->s[i] = xstrdup(src->s[i]); \ 2282 dst->num_s = src->num_s; \ 2283 } \ 2284 } while(0) 2285 2286 /* See comment in servconf.h */ 2287 COPY_MATCH_STRING_OPTS(); 2288 2289 /* Arguments that accept '+...' need to be expanded */ 2290 assemble_algorithms(dst); 2291 2292 /* 2293 * The only things that should be below this point are string options 2294 * which are only used after authentication. 2295 */ 2296 if (preauth) 2297 return; 2298 2299 /* These options may be "none" to clear a global setting */ 2300 M_CP_STROPT(adm_forced_command); 2301 if (option_clear_or_none(dst->adm_forced_command)) { 2302 free(dst->adm_forced_command); 2303 dst->adm_forced_command = NULL; 2304 } 2305 M_CP_STROPT(chroot_directory); 2306 if (option_clear_or_none(dst->chroot_directory)) { 2307 free(dst->chroot_directory); 2308 dst->chroot_directory = NULL; 2309 } 2310 } 2311 2312 #undef M_CP_INTOPT 2313 #undef M_CP_STROPT 2314 #undef M_CP_STRARRAYOPT 2315 2316 void 2317 parse_server_config(ServerOptions *options, const char *filename, 2318 struct sshbuf *conf, struct connection_info *connectinfo) 2319 { 2320 int active, linenum, bad_options = 0; 2321 char *cp, *obuf, *cbuf; 2322 2323 debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf)); 2324 2325 if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) 2326 fatal("%s: sshbuf_dup_string failed", __func__); 2327 active = connectinfo ? 0 : 1; 2328 linenum = 1; 2329 while ((cp = strsep(&cbuf, "\n")) != NULL) { 2330 if (process_server_config_line(options, cp, filename, 2331 linenum++, &active, connectinfo) != 0) 2332 bad_options++; 2333 } 2334 free(obuf); 2335 if (bad_options > 0) 2336 fatal("%s: terminating, %d bad configuration options", 2337 filename, bad_options); 2338 process_queued_listen_addrs(options); 2339 } 2340 2341 static const char * 2342 fmt_multistate_int(int val, const struct multistate *m) 2343 { 2344 u_int i; 2345 2346 for (i = 0; m[i].key != NULL; i++) { 2347 if (m[i].value == val) 2348 return m[i].key; 2349 } 2350 return "UNKNOWN"; 2351 } 2352 2353 static const char * 2354 fmt_intarg(ServerOpCodes code, int val) 2355 { 2356 if (val == -1) 2357 return "unset"; 2358 switch (code) { 2359 case sAddressFamily: 2360 return fmt_multistate_int(val, multistate_addressfamily); 2361 case sPermitRootLogin: 2362 return fmt_multistate_int(val, multistate_permitrootlogin); 2363 case sGatewayPorts: 2364 return fmt_multistate_int(val, multistate_gatewayports); 2365 case sCompression: 2366 return fmt_multistate_int(val, multistate_compression); 2367 case sAllowTcpForwarding: 2368 return fmt_multistate_int(val, multistate_tcpfwd); 2369 case sAllowStreamLocalForwarding: 2370 return fmt_multistate_int(val, multistate_tcpfwd); 2371 case sFingerprintHash: 2372 return ssh_digest_alg_name(val); 2373 default: 2374 switch (val) { 2375 case 0: 2376 return "no"; 2377 case 1: 2378 return "yes"; 2379 default: 2380 return "UNKNOWN"; 2381 } 2382 } 2383 } 2384 2385 static void 2386 dump_cfg_int(ServerOpCodes code, int val) 2387 { 2388 printf("%s %d\n", lookup_opcode_name(code), val); 2389 } 2390 2391 static void 2392 dump_cfg_oct(ServerOpCodes code, int val) 2393 { 2394 printf("%s 0%o\n", lookup_opcode_name(code), val); 2395 } 2396 2397 static void 2398 dump_cfg_fmtint(ServerOpCodes code, int val) 2399 { 2400 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 2401 } 2402 2403 static void 2404 dump_cfg_string(ServerOpCodes code, const char *val) 2405 { 2406 printf("%s %s\n", lookup_opcode_name(code), 2407 val == NULL ? "none" : val); 2408 } 2409 2410 static void 2411 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) 2412 { 2413 u_int i; 2414 2415 for (i = 0; i < count; i++) 2416 printf("%s %s\n", lookup_opcode_name(code), vals[i]); 2417 } 2418 2419 static void 2420 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals) 2421 { 2422 u_int i; 2423 2424 if (count <= 0 && code != sAuthenticationMethods) 2425 return; 2426 printf("%s", lookup_opcode_name(code)); 2427 for (i = 0; i < count; i++) 2428 printf(" %s", vals[i]); 2429 if (code == sAuthenticationMethods && count == 0) 2430 printf(" any"); 2431 printf("\n"); 2432 } 2433 2434 static char * 2435 format_listen_addrs(struct listenaddr *la) 2436 { 2437 int r; 2438 struct addrinfo *ai; 2439 char addr[NI_MAXHOST], port[NI_MAXSERV]; 2440 char *laddr1 = xstrdup(""), *laddr2 = NULL; 2441 2442 /* 2443 * ListenAddress must be after Port. add_one_listen_addr pushes 2444 * addresses onto a stack, so to maintain ordering we need to 2445 * print these in reverse order. 2446 */ 2447 for (ai = la->addrs; ai; ai = ai->ai_next) { 2448 if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, 2449 sizeof(addr), port, sizeof(port), 2450 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 2451 error("getnameinfo: %.100s", ssh_gai_strerror(r)); 2452 continue; 2453 } 2454 laddr2 = laddr1; 2455 if (ai->ai_family == AF_INET6) { 2456 xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s", 2457 addr, port, 2458 la->rdomain == NULL ? "" : " rdomain ", 2459 la->rdomain == NULL ? "" : la->rdomain, 2460 laddr2); 2461 } else { 2462 xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s", 2463 addr, port, 2464 la->rdomain == NULL ? "" : " rdomain ", 2465 la->rdomain == NULL ? "" : la->rdomain, 2466 laddr2); 2467 } 2468 free(laddr2); 2469 } 2470 return laddr1; 2471 } 2472 2473 void 2474 dump_config(ServerOptions *o) 2475 { 2476 char *s; 2477 u_int i; 2478 2479 /* these are usually at the top of the config */ 2480 for (i = 0; i < o->num_ports; i++) 2481 printf("port %d\n", o->ports[i]); 2482 dump_cfg_fmtint(sAddressFamily, o->address_family); 2483 2484 for (i = 0; i < o->num_listen_addrs; i++) { 2485 s = format_listen_addrs(&o->listen_addrs[i]); 2486 printf("%s", s); 2487 free(s); 2488 } 2489 2490 /* integer arguments */ 2491 dump_cfg_int(sLoginGraceTime, o->login_grace_time); 2492 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); 2493 dump_cfg_int(sMaxAuthTries, o->max_authtries); 2494 dump_cfg_int(sMaxSessions, o->max_sessions); 2495 dump_cfg_int(sClientAliveInterval, o->client_alive_interval); 2496 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); 2497 dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); 2498 2499 /* formatted integer arguments */ 2500 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); 2501 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); 2502 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); 2503 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); 2504 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, 2505 o->hostbased_uses_name_from_packet_only); 2506 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); 2507 #ifdef KRB5 2508 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); 2509 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); 2510 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); 2511 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); 2512 #endif 2513 #ifdef GSSAPI 2514 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); 2515 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); 2516 #endif 2517 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); 2518 dump_cfg_fmtint(sKbdInteractiveAuthentication, 2519 o->kbd_interactive_authentication); 2520 dump_cfg_fmtint(sChallengeResponseAuthentication, 2521 o->challenge_response_authentication); 2522 dump_cfg_fmtint(sPrintMotd, o->print_motd); 2523 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); 2524 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); 2525 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); 2526 dump_cfg_fmtint(sPermitTTY, o->permit_tty); 2527 dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc); 2528 dump_cfg_fmtint(sStrictModes, o->strict_modes); 2529 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); 2530 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); 2531 dump_cfg_fmtint(sCompression, o->compression); 2532 dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); 2533 dump_cfg_fmtint(sUseDNS, o->use_dns); 2534 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); 2535 dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); 2536 dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding); 2537 dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); 2538 dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 2539 dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); 2540 dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info); 2541 2542 /* string arguments */ 2543 dump_cfg_string(sPidFile, o->pid_file); 2544 dump_cfg_string(sXAuthLocation, o->xauth_location); 2545 dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); 2546 dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); 2547 dump_cfg_string(sBanner, o->banner); 2548 dump_cfg_string(sForceCommand, o->adm_forced_command); 2549 dump_cfg_string(sChrootDirectory, o->chroot_directory); 2550 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); 2551 dump_cfg_string(sRevokedKeys, o->revoked_keys_file); 2552 dump_cfg_string(sAuthorizedPrincipalsFile, 2553 o->authorized_principals_file); 2554 dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' 2555 ? "none" : o->version_addendum); 2556 dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); 2557 dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); 2558 dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); 2559 dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); 2560 dump_cfg_string(sHostKeyAgent, o->host_key_agent); 2561 dump_cfg_string(sKexAlgorithms, 2562 o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); 2563 dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms ? 2564 o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS); 2565 dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? 2566 o->hostbased_key_types : KEX_DEFAULT_PK_ALG); 2567 dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? 2568 o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); 2569 dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? 2570 o->pubkey_key_types : KEX_DEFAULT_PK_ALG); 2571 dump_cfg_string(sRDomain, o->routing_domain); 2572 2573 /* string arguments requiring a lookup */ 2574 dump_cfg_string(sLogLevel, log_level_name(o->log_level)); 2575 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); 2576 2577 /* string array arguments */ 2578 dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files, 2579 o->authorized_keys_files); 2580 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, 2581 o->host_key_files); 2582 dump_cfg_strarray(sHostCertificate, o->num_host_cert_files, 2583 o->host_cert_files); 2584 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); 2585 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); 2586 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); 2587 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); 2588 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); 2589 dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv); 2590 dump_cfg_strarray_oneline(sAuthenticationMethods, 2591 o->num_auth_methods, o->auth_methods); 2592 2593 /* other arguments */ 2594 for (i = 0; i < o->num_subsystems; i++) 2595 printf("subsystem %s %s\n", o->subsystem_name[i], 2596 o->subsystem_args[i]); 2597 2598 printf("maxstartups %d:%d:%d\n", o->max_startups_begin, 2599 o->max_startups_rate, o->max_startups); 2600 2601 s = NULL; 2602 for (i = 0; tunmode_desc[i].val != -1; i++) { 2603 if (tunmode_desc[i].val == o->permit_tun) { 2604 s = tunmode_desc[i].text; 2605 break; 2606 } 2607 } 2608 dump_cfg_string(sPermitTunnel, s); 2609 2610 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2611 printf("%s\n", iptos2str(o->ip_qos_bulk)); 2612 2613 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit, 2614 o->rekey_interval); 2615 2616 printf("permitopen"); 2617 if (o->num_permitted_opens == 0) 2618 printf(" any"); 2619 else { 2620 for (i = 0; i < o->num_permitted_opens; i++) 2621 printf(" %s", o->permitted_opens[i]); 2622 } 2623 printf("\n"); 2624 printf("permitlisten"); 2625 if (o->num_permitted_listens == 0) 2626 printf(" any"); 2627 else { 2628 for (i = 0; i < o->num_permitted_listens; i++) 2629 printf(" %s", o->permitted_listens[i]); 2630 } 2631 printf("\n"); 2632 2633 if (o->permit_user_env_whitelist == NULL) { 2634 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); 2635 } else { 2636 printf("permituserenvironment %s\n", 2637 o->permit_user_env_whitelist); 2638 } 2639 2640 } 2641