1 /* $NetBSD: readconf.c,v 1.31 2020/05/28 17:05:49 christos Exp $ */ 2 /* $OpenBSD: readconf.c,v 1.329 2020/04/24 03:33:21 dtucker Exp $ */ 3 /* 4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 6 * All rights reserved 7 * Functions for reading the configuration files. 8 * 9 * As far as I am concerned, the code I have written for this software 10 * can be used freely for any purpose. Any derived versions of this 11 * software must be clearly marked as such, and if the derived work is 12 * incompatible with the protocol description in the RFC file, it must be 13 * called by a name other than "ssh" or "Secure Shell". 14 */ 15 16 #include "includes.h" 17 __RCSID("$NetBSD: readconf.c,v 1.31 2020/05/28 17:05:49 christos Exp $"); 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <sys/socket.h> 21 #include <sys/wait.h> 22 #include <sys/un.h> 23 24 #include <netinet/in.h> 25 #include <netinet/ip.h> 26 27 #include <ctype.h> 28 #include <errno.h> 29 #include <fcntl.h> 30 #include <glob.h> 31 #include <netdb.h> 32 #include <paths.h> 33 #include <pwd.h> 34 #include <signal.h> 35 #include <stdio.h> 36 #include <string.h> 37 #include <stdarg.h> 38 #include <unistd.h> 39 #include <limits.h> 40 #include <util.h> 41 #include <vis.h> 42 43 #include "xmalloc.h" 44 #include "ssh.h" 45 #include "ssherr.h" 46 #include "compat.h" 47 #include "cipher.h" 48 #include "pathnames.h" 49 #include "log.h" 50 #include "sshkey.h" 51 #include "misc.h" 52 #include "readconf.h" 53 #include "match.h" 54 #include "kex.h" 55 #include "mac.h" 56 #include "fmt_scaled.h" 57 #include "uidswap.h" 58 #include "myproposal.h" 59 #include "digest.h" 60 61 /* Format of the configuration file: 62 63 # Configuration data is parsed as follows: 64 # 1. command line options 65 # 2. user-specific file 66 # 3. system-wide file 67 # Any configuration value is only changed the first time it is set. 68 # Thus, host-specific definitions should be at the beginning of the 69 # configuration file, and defaults at the end. 70 71 # Host-specific declarations. These may override anything above. A single 72 # host may match multiple declarations; these are processed in the order 73 # that they are given in. 74 75 Host *.ngs.fi ngs.fi 76 User foo 77 78 Host fake.com 79 Hostname another.host.name.real.org 80 User blaah 81 Port 34289 82 ForwardX11 no 83 ForwardAgent no 84 85 Host books.com 86 RemoteForward 9999 shadows.cs.hut.fi:9999 87 Ciphers 3des-cbc 88 89 Host fascist.blob.com 90 Port 23123 91 User tylonen 92 PasswordAuthentication no 93 94 Host puukko.hut.fi 95 User t35124p 96 ProxyCommand ssh-proxy %h %p 97 98 Host *.fr 99 PublicKeyAuthentication no 100 101 Host *.su 102 Ciphers aes128-ctr 103 PasswordAuthentication no 104 105 Host vpn.fake.com 106 Tunnel yes 107 TunnelDevice 3 108 109 # Defaults for various options 110 Host * 111 ForwardAgent no 112 ForwardX11 no 113 PasswordAuthentication yes 114 StrictHostKeyChecking yes 115 TcpKeepAlive no 116 IdentityFile ~/.ssh/identity 117 Port 22 118 EscapeChar ~ 119 120 */ 121 122 static int read_config_file_depth(const char *filename, struct passwd *pw, 123 const char *host, const char *original_host, Options *options, 124 int flags, int *activep, int *want_final_pass, int depth); 125 static int process_config_line_depth(Options *options, struct passwd *pw, 126 const char *host, const char *original_host, char *line, 127 const char *filename, int linenum, int *activep, int flags, 128 int *want_final_pass, int depth); 129 130 /* Keyword tokens. */ 131 132 typedef enum { 133 oBadOption, 134 oHost, oMatch, oInclude, 135 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout, 136 oGatewayPorts, oExitOnForwardFailure, 137 oPasswordAuthentication, 138 oChallengeResponseAuthentication, oXAuthLocation, 139 #if defined(KRB4) || defined(KRB5) 140 oKerberosAuthentication, 141 #endif 142 #if defined(AFS) || defined(KRB5) 143 oKerberosTgtPassing, 144 #endif 145 #ifdef AFS 146 oAFSTokenPassing, 147 #endif 148 oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward, 149 oCertificateFile, oAddKeysToAgent, oIdentityAgent, 150 oUser, oEscapeChar, oProxyCommand, 151 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 152 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 153 oTCPKeepAlive, oNumberOfPasswordPrompts, 154 oLogFacility, oLogLevel, oCiphers, oMacs, 155 oPubkeyAuthentication, 156 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 157 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 158 oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider, 159 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 160 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 161 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 162 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 163 oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, 164 oHashKnownHosts, 165 oTunnel, oTunnelDevice, 166 oLocalCommand, oPermitLocalCommand, oRemoteCommand, 167 oVisualHostKey, 168 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 169 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, 170 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, 171 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, 172 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, 173 oPubkeyAcceptedKeyTypes, oCASignatureAlgorithms, oProxyJump, 174 oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled, 175 oHPNBufferSize, 176 oSendVersionFirst, 177 oSecurityKeyProvider, 178 oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported 179 } OpCodes; 180 181 /* Textual representations of the tokens. */ 182 183 static struct { 184 const char *name; 185 OpCodes opcode; 186 } keywords[] = { 187 /* Deprecated options */ 188 { "protocol", oIgnore }, /* NB. silently ignored */ 189 { "cipher", oDeprecated }, 190 { "fallbacktorsh", oDeprecated }, 191 { "globalknownhostsfile2", oDeprecated }, 192 { "rhostsauthentication", oDeprecated }, 193 { "userknownhostsfile2", oDeprecated }, 194 { "useroaming", oDeprecated }, 195 { "usersh", oDeprecated }, 196 { "useprivilegedport", oDeprecated }, 197 198 /* Unsupported options */ 199 #ifdef AFS 200 { "afstokenpassing", oAFSTokenPassing }, 201 #else 202 { "afstokenpassing", oUnsupported }, 203 #endif 204 #if defined(KRB4) || defined(KRB5) 205 { "kerberosauthentication", oKerberosAuthentication }, 206 #else 207 { "kerberosauthentication", oUnsupported }, 208 #endif 209 #if defined(AFS) || defined(KRB5) 210 { "kerberostgtpassing", oKerberosTgtPassing }, 211 { "kerberos5tgtpassing", oKerberosTgtPassing }, /* alias */ 212 { "kerberos4tgtpassing", oKerberosTgtPassing }, /* alias */ 213 #else 214 { "kerberostgtpassing", oUnsupported }, 215 { "kerberos5tgtpassing", oUnsupported }, 216 { "kerberos4tgtpassing", oUnsupported }, 217 #endif 218 { "rsaauthentication", oUnsupported }, 219 { "rhostsrsaauthentication", oUnsupported }, 220 { "compressionlevel", oUnsupported }, 221 222 /* Sometimes-unsupported options */ 223 #if defined(GSSAPI) 224 { "gssapiauthentication", oGssAuthentication }, 225 { "gssapidelegatecredentials", oGssDelegateCreds }, 226 # else 227 { "gssapiauthentication", oUnsupported }, 228 { "gssapidelegatecredentials", oUnsupported }, 229 #endif 230 #ifdef ENABLE_PKCS11 231 { "pkcs11provider", oPKCS11Provider }, 232 { "smartcarddevice", oPKCS11Provider }, 233 # else 234 { "smartcarddevice", oUnsupported }, 235 { "pkcs11provider", oUnsupported }, 236 #endif 237 238 { "forwardagent", oForwardAgent }, 239 { "forwardx11", oForwardX11 }, 240 { "forwardx11trusted", oForwardX11Trusted }, 241 { "forwardx11timeout", oForwardX11Timeout }, 242 { "exitonforwardfailure", oExitOnForwardFailure }, 243 { "xauthlocation", oXAuthLocation }, 244 { "gatewayports", oGatewayPorts }, 245 { "passwordauthentication", oPasswordAuthentication }, 246 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 247 { "kbdinteractivedevices", oKbdInteractiveDevices }, 248 { "pubkeyauthentication", oPubkeyAuthentication }, 249 { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 250 { "hostbasedauthentication", oHostbasedAuthentication }, 251 { "challengeresponseauthentication", oChallengeResponseAuthentication }, 252 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 253 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 254 #if defined(GSSAPI) 255 { "gssapiauthentication", oGssAuthentication }, 256 { "gssapidelegatecredentials", oGssDelegateCreds }, 257 #else 258 { "gssapiauthentication", oUnsupported }, 259 { "gssapidelegatecredentials", oUnsupported }, 260 #endif 261 { "identityfile", oIdentityFile }, 262 { "identityfile2", oIdentityFile }, /* obsolete */ 263 { "identitiesonly", oIdentitiesOnly }, 264 { "certificatefile", oCertificateFile }, 265 { "addkeystoagent", oAddKeysToAgent }, 266 { "identityagent", oIdentityAgent }, 267 { "hostname", oHostname }, 268 { "hostkeyalias", oHostKeyAlias }, 269 { "proxycommand", oProxyCommand }, 270 { "port", oPort }, 271 { "ciphers", oCiphers }, 272 { "macs", oMacs }, 273 { "remoteforward", oRemoteForward }, 274 { "localforward", oLocalForward }, 275 { "user", oUser }, 276 { "host", oHost }, 277 { "match", oMatch }, 278 { "escapechar", oEscapeChar }, 279 { "globalknownhostsfile", oGlobalKnownHostsFile }, 280 { "userknownhostsfile", oUserKnownHostsFile }, 281 { "connectionattempts", oConnectionAttempts }, 282 { "batchmode", oBatchMode }, 283 { "checkhostip", oCheckHostIP }, 284 { "stricthostkeychecking", oStrictHostKeyChecking }, 285 { "compression", oCompression }, 286 { "tcpkeepalive", oTCPKeepAlive }, 287 { "keepalive", oTCPKeepAlive }, /* obsolete */ 288 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 289 { "syslogfacility", oLogFacility }, 290 { "loglevel", oLogLevel }, 291 { "dynamicforward", oDynamicForward }, 292 { "preferredauthentications", oPreferredAuthentications }, 293 { "hostkeyalgorithms", oHostKeyAlgorithms }, 294 { "casignaturealgorithms", oCASignatureAlgorithms }, 295 { "bindaddress", oBindAddress }, 296 { "bindinterface", oBindInterface }, 297 { "clearallforwardings", oClearAllForwardings }, 298 { "enablesshkeysign", oEnableSSHKeysign }, 299 { "verifyhostkeydns", oVerifyHostKeyDNS }, 300 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 301 { "rekeylimit", oRekeyLimit }, 302 { "connecttimeout", oConnectTimeout }, 303 { "addressfamily", oAddressFamily }, 304 { "serveraliveinterval", oServerAliveInterval }, 305 { "serveralivecountmax", oServerAliveCountMax }, 306 { "sendenv", oSendEnv }, 307 { "setenv", oSetEnv }, 308 { "controlpath", oControlPath }, 309 { "controlmaster", oControlMaster }, 310 { "controlpersist", oControlPersist }, 311 { "hashknownhosts", oHashKnownHosts }, 312 { "include", oInclude }, 313 { "tunnel", oTunnel }, 314 { "tunneldevice", oTunnelDevice }, 315 { "localcommand", oLocalCommand }, 316 { "permitlocalcommand", oPermitLocalCommand }, 317 { "remotecommand", oRemoteCommand }, 318 { "visualhostkey", oVisualHostKey }, 319 { "kexalgorithms", oKexAlgorithms }, 320 { "ipqos", oIPQoS }, 321 { "requesttty", oRequestTTY }, 322 { "proxyusefdpass", oProxyUseFdpass }, 323 { "canonicaldomains", oCanonicalDomains }, 324 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, 325 { "canonicalizehostname", oCanonicalizeHostname }, 326 { "canonicalizemaxdots", oCanonicalizeMaxDots }, 327 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, 328 { "streamlocalbindmask", oStreamLocalBindMask }, 329 { "streamlocalbindunlink", oStreamLocalBindUnlink }, 330 { "revokedhostkeys", oRevokedHostKeys }, 331 { "fingerprinthash", oFingerprintHash }, 332 { "updatehostkeys", oUpdateHostkeys }, 333 { "hostbasedkeytypes", oHostbasedKeyTypes }, 334 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes }, 335 { "proxyjump", oProxyJump }, 336 { "noneenabled", oNoneEnabled }, 337 { "tcprcvbufpoll", oTcpRcvBufPoll }, 338 { "tcprcvbuf", oTcpRcvBuf }, 339 { "noneswitch", oNoneSwitch }, 340 { "hpndisabled", oHPNDisabled }, 341 { "hpnbuffersize", oHPNBufferSize }, 342 { "sendversionfirst", oSendVersionFirst }, 343 { "ignoreunknown", oIgnoreUnknown }, 344 { "proxyjump", oProxyJump }, 345 { "securitykeyprovider", oSecurityKeyProvider }, 346 347 { NULL, oBadOption } 348 }; 349 350 static char *kex_default_pk_alg_filtered; 351 352 const char * 353 kex_default_pk_alg(void) 354 { 355 if (kex_default_pk_alg_filtered == NULL) 356 fatal("kex_default_pk_alg not initialized."); 357 return kex_default_pk_alg_filtered; 358 } 359 360 char * 361 ssh_connection_hash(const char *thishost, const char *host, const char *portstr, 362 const char *user) 363 { 364 struct ssh_digest_ctx *md; 365 u_char conn_hash[SSH_DIGEST_MAX_LENGTH]; 366 367 if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL || 368 ssh_digest_update(md, thishost, strlen(thishost)) < 0 || 369 ssh_digest_update(md, host, strlen(host)) < 0 || 370 ssh_digest_update(md, portstr, strlen(portstr)) < 0 || 371 ssh_digest_update(md, user, strlen(user)) < 0 || 372 ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0) 373 fatal("%s: mux digest failed", __func__); 374 ssh_digest_free(md); 375 return tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); 376 } 377 378 /* 379 * Adds a local TCP/IP port forward to options. Never returns if there is an 380 * error. 381 */ 382 383 void 384 add_local_forward(Options *options, const struct Forward *newfwd) 385 { 386 struct Forward *fwd; 387 int i; 388 389 /* Don't add duplicates */ 390 for (i = 0; i < options->num_local_forwards; i++) { 391 if (forward_equals(newfwd, options->local_forwards + i)) 392 return; 393 } 394 options->local_forwards = xreallocarray(options->local_forwards, 395 options->num_local_forwards + 1, 396 sizeof(*options->local_forwards)); 397 fwd = &options->local_forwards[options->num_local_forwards++]; 398 399 fwd->listen_host = newfwd->listen_host; 400 fwd->listen_port = newfwd->listen_port; 401 fwd->listen_path = newfwd->listen_path; 402 fwd->connect_host = newfwd->connect_host; 403 fwd->connect_port = newfwd->connect_port; 404 fwd->connect_path = newfwd->connect_path; 405 } 406 407 /* 408 * Adds a remote TCP/IP port forward to options. Never returns if there is 409 * an error. 410 */ 411 412 void 413 add_remote_forward(Options *options, const struct Forward *newfwd) 414 { 415 struct Forward *fwd; 416 int i; 417 418 /* Don't add duplicates */ 419 for (i = 0; i < options->num_remote_forwards; i++) { 420 if (forward_equals(newfwd, options->remote_forwards + i)) 421 return; 422 } 423 options->remote_forwards = xreallocarray(options->remote_forwards, 424 options->num_remote_forwards + 1, 425 sizeof(*options->remote_forwards)); 426 fwd = &options->remote_forwards[options->num_remote_forwards++]; 427 428 fwd->listen_host = newfwd->listen_host; 429 fwd->listen_port = newfwd->listen_port; 430 fwd->listen_path = newfwd->listen_path; 431 fwd->connect_host = newfwd->connect_host; 432 fwd->connect_port = newfwd->connect_port; 433 fwd->connect_path = newfwd->connect_path; 434 fwd->handle = newfwd->handle; 435 fwd->allocated_port = 0; 436 } 437 438 static void 439 clear_forwardings(Options *options) 440 { 441 int i; 442 443 for (i = 0; i < options->num_local_forwards; i++) { 444 free(options->local_forwards[i].listen_host); 445 free(options->local_forwards[i].listen_path); 446 free(options->local_forwards[i].connect_host); 447 free(options->local_forwards[i].connect_path); 448 } 449 if (options->num_local_forwards > 0) { 450 free(options->local_forwards); 451 options->local_forwards = NULL; 452 } 453 options->num_local_forwards = 0; 454 for (i = 0; i < options->num_remote_forwards; i++) { 455 free(options->remote_forwards[i].listen_host); 456 free(options->remote_forwards[i].listen_path); 457 free(options->remote_forwards[i].connect_host); 458 free(options->remote_forwards[i].connect_path); 459 } 460 if (options->num_remote_forwards > 0) { 461 free(options->remote_forwards); 462 options->remote_forwards = NULL; 463 } 464 options->num_remote_forwards = 0; 465 options->tun_open = SSH_TUNMODE_NO; 466 } 467 468 void 469 add_certificate_file(Options *options, const char *path, int userprovided) 470 { 471 int i; 472 473 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES) 474 fatal("Too many certificate files specified (max %d)", 475 SSH_MAX_CERTIFICATE_FILES); 476 477 /* Avoid registering duplicates */ 478 for (i = 0; i < options->num_certificate_files; i++) { 479 if (options->certificate_file_userprovided[i] == userprovided && 480 strcmp(options->certificate_files[i], path) == 0) { 481 debug2("%s: ignoring duplicate key %s", __func__, path); 482 return; 483 } 484 } 485 486 options->certificate_file_userprovided[options->num_certificate_files] = 487 userprovided; 488 options->certificate_files[options->num_certificate_files++] = 489 xstrdup(path); 490 } 491 492 void 493 add_identity_file(Options *options, const char *dir, const char *filename, 494 int userprovided) 495 { 496 char *path; 497 int i; 498 499 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 500 fatal("Too many identity files specified (max %d)", 501 SSH_MAX_IDENTITY_FILES); 502 503 if (dir == NULL) /* no dir, filename is absolute */ 504 path = xstrdup(filename); 505 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX) 506 fatal("Identity file path %s too long", path); 507 508 /* Avoid registering duplicates */ 509 for (i = 0; i < options->num_identity_files; i++) { 510 if (options->identity_file_userprovided[i] == userprovided && 511 strcmp(options->identity_files[i], path) == 0) { 512 debug2("%s: ignoring duplicate key %s", __func__, path); 513 free(path); 514 return; 515 } 516 } 517 518 options->identity_file_userprovided[options->num_identity_files] = 519 userprovided; 520 options->identity_files[options->num_identity_files++] = path; 521 } 522 523 int 524 default_ssh_port(void) 525 { 526 static int port; 527 struct servent *sp; 528 529 if (port == 0) { 530 sp = getservbyname(SSH_SERVICE_NAME, "tcp"); 531 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; 532 } 533 return port; 534 } 535 536 /* 537 * Execute a command in a shell. 538 * Return its exit status or -1 on abnormal exit. 539 */ 540 static int 541 execute_in_shell(const char *cmd) 542 { 543 const char *shell; 544 pid_t pid; 545 int devnull, status; 546 547 if ((shell = getenv("SHELL")) == NULL) 548 shell = _PATH_BSHELL; 549 550 if (access(shell, X_OK) == -1) { 551 fatal("Shell \"%s\" is not executable: %s", 552 shell, strerror(errno)); 553 } 554 555 /* Need this to redirect subprocess stdin/out */ 556 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) 557 fatal("open(/dev/null): %s", strerror(errno)); 558 559 debug("Executing command: '%.500s'", cmd); 560 561 /* Fork and execute the command. */ 562 if ((pid = fork()) == 0) { 563 char *argv[4]; 564 565 /* Redirect child stdin and stdout. Leave stderr */ 566 if (dup2(devnull, STDIN_FILENO) == -1) 567 fatal("dup2: %s", strerror(errno)); 568 if (dup2(devnull, STDOUT_FILENO) == -1) 569 fatal("dup2: %s", strerror(errno)); 570 if (devnull > STDERR_FILENO) 571 close(devnull); 572 if (closefrom(STDERR_FILENO + 1) == -1) 573 fatal("closefrom: %s", strerror(errno)); 574 575 argv[0] = __UNCONST(shell); 576 argv[1] = __UNCONST("-c"); 577 argv[2] = xstrdup(cmd); 578 argv[3] = NULL; 579 580 execv(argv[0], argv); 581 error("Unable to execute '%.100s': %s", cmd, strerror(errno)); 582 /* Die with signal to make this error apparent to parent. */ 583 ssh_signal(SIGTERM, SIG_DFL); 584 kill(getpid(), SIGTERM); 585 _exit(1); 586 } 587 /* Parent. */ 588 if (pid == -1) 589 fatal("%s: fork: %.100s", __func__, strerror(errno)); 590 591 close(devnull); 592 593 while (waitpid(pid, &status, 0) == -1) { 594 if (errno != EINTR && errno != EAGAIN) 595 fatal("%s: waitpid: %s", __func__, strerror(errno)); 596 } 597 if (!WIFEXITED(status)) { 598 error("command '%.100s' exited abnormally", cmd); 599 return -1; 600 } 601 debug3("command returned status %d", WEXITSTATUS(status)); 602 return WEXITSTATUS(status); 603 } 604 605 /* 606 * Parse and execute a Match directive. 607 */ 608 static int 609 match_cfg_line(Options *options, char **condition, struct passwd *pw, 610 const char *host_arg, const char *original_host, int final_pass, 611 int *want_final_pass, const char *filename, int linenum) 612 { 613 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; 614 const char *ruser; 615 int r, port, this_result, result = 1, attributes = 0, negate; 616 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; 617 char uidstr[32]; 618 619 /* 620 * Configuration is likely to be incomplete at this point so we 621 * must be prepared to use default values. 622 */ 623 port = options->port <= 0 ? default_ssh_port() : options->port; 624 ruser = options->user == NULL ? pw->pw_name : options->user; 625 if (final_pass) { 626 host = xstrdup(options->hostname); 627 } else if (options->hostname != NULL) { 628 /* NB. Please keep in sync with ssh.c:main() */ 629 host = percent_expand(options->hostname, 630 "h", host_arg, (char *)NULL); 631 } else { 632 host = xstrdup(host_arg); 633 } 634 635 debug2("checking match for '%s' host %s originally %s", 636 cp, host, original_host); 637 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { 638 criteria = NULL; 639 this_result = 1; 640 if ((negate = attrib[0] == '!')) 641 attrib++; 642 /* criteria "all" and "canonical" have no argument */ 643 if (strcasecmp(attrib, "all") == 0) { 644 if (attributes > 1 || 645 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { 646 error("%.200s line %d: '%s' cannot be combined " 647 "with other Match attributes", 648 filename, linenum, oattrib); 649 result = -1; 650 goto out; 651 } 652 if (result) 653 result = negate ? 0 : 1; 654 goto out; 655 } 656 attributes++; 657 if (strcasecmp(attrib, "canonical") == 0 || 658 strcasecmp(attrib, "final") == 0) { 659 /* 660 * If the config requests "Match final" then remember 661 * this so we can perform a second pass later. 662 */ 663 if (strcasecmp(attrib, "final") == 0 && 664 want_final_pass != NULL) 665 *want_final_pass = 1; 666 r = !!final_pass; /* force bitmask member to boolean */ 667 if (r == (negate ? 1 : 0)) 668 this_result = result = 0; 669 debug3("%.200s line %d: %smatched '%s'", 670 filename, linenum, 671 this_result ? "" : "not ", oattrib); 672 continue; 673 } 674 /* All other criteria require an argument */ 675 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { 676 error("Missing Match criteria for %s", attrib); 677 result = -1; 678 goto out; 679 } 680 if (strcasecmp(attrib, "host") == 0) { 681 criteria = xstrdup(host); 682 r = match_hostname(host, arg) == 1; 683 if (r == (negate ? 1 : 0)) 684 this_result = result = 0; 685 } else if (strcasecmp(attrib, "originalhost") == 0) { 686 criteria = xstrdup(original_host); 687 r = match_hostname(original_host, arg) == 1; 688 if (r == (negate ? 1 : 0)) 689 this_result = result = 0; 690 } else if (strcasecmp(attrib, "user") == 0) { 691 criteria = xstrdup(ruser); 692 r = match_pattern_list(ruser, arg, 0) == 1; 693 if (r == (negate ? 1 : 0)) 694 this_result = result = 0; 695 } else if (strcasecmp(attrib, "localuser") == 0) { 696 criteria = xstrdup(pw->pw_name); 697 r = match_pattern_list(pw->pw_name, arg, 0) == 1; 698 if (r == (negate ? 1 : 0)) 699 this_result = result = 0; 700 } else if (strcasecmp(attrib, "exec") == 0) { 701 char *conn_hash_hex; 702 703 if (gethostname(thishost, sizeof(thishost)) == -1) 704 fatal("gethostname: %s", strerror(errno)); 705 strlcpy(shorthost, thishost, sizeof(shorthost)); 706 shorthost[strcspn(thishost, ".")] = '\0'; 707 snprintf(portstr, sizeof(portstr), "%d", port); 708 snprintf(uidstr, sizeof(uidstr), "%llu", 709 (unsigned long long)pw->pw_uid); 710 conn_hash_hex = ssh_connection_hash(thishost, host, 711 portstr, ruser); 712 713 cmd = percent_expand(arg, 714 "C", conn_hash_hex, 715 "L", shorthost, 716 "d", pw->pw_dir, 717 "h", host, 718 "l", thishost, 719 "n", original_host, 720 "p", portstr, 721 "r", ruser, 722 "u", pw->pw_name, 723 "i", uidstr, 724 (char *)NULL); 725 free(conn_hash_hex); 726 if (result != 1) { 727 /* skip execution if prior predicate failed */ 728 debug3("%.200s line %d: skipped exec " 729 "\"%.100s\"", filename, linenum, cmd); 730 free(cmd); 731 continue; 732 } 733 r = execute_in_shell(cmd); 734 if (r == -1) { 735 fatal("%.200s line %d: match exec " 736 "'%.100s' error", filename, 737 linenum, cmd); 738 } 739 criteria = xstrdup(cmd); 740 free(cmd); 741 /* Force exit status to boolean */ 742 r = r == 0; 743 if (r == (negate ? 1 : 0)) 744 this_result = result = 0; 745 } else { 746 error("Unsupported Match attribute %s", attrib); 747 result = -1; 748 goto out; 749 } 750 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ", 751 filename, linenum, this_result ? "": "not ", 752 oattrib, criteria); 753 free(criteria); 754 } 755 if (attributes == 0) { 756 error("One or more attributes required for Match"); 757 result = -1; 758 goto out; 759 } 760 out: 761 if (result != -1) 762 debug2("match %sfound", result ? "" : "not "); 763 *condition = cp; 764 free(host); 765 return result; 766 } 767 768 /* Remove environment variable by pattern */ 769 static void 770 rm_env(Options *options, const char *arg, const char *filename, int linenum) 771 { 772 int i, j; 773 char *cp; 774 775 /* Remove an environment variable */ 776 for (i = 0; i < options->num_send_env; ) { 777 cp = xstrdup(options->send_env[i]); 778 if (!match_pattern(cp, arg + 1)) { 779 free(cp); 780 i++; 781 continue; 782 } 783 debug3("%s line %d: removing environment %s", 784 filename, linenum, cp); 785 free(cp); 786 free(options->send_env[i]); 787 options->send_env[i] = NULL; 788 for (j = i; j < options->num_send_env - 1; j++) { 789 options->send_env[j] = options->send_env[j + 1]; 790 options->send_env[j + 1] = NULL; 791 } 792 options->num_send_env--; 793 /* NB. don't increment i */ 794 } 795 } 796 797 /* 798 * Returns the number of the token pointed to by cp or oBadOption. 799 */ 800 static OpCodes 801 parse_token(const char *cp, const char *filename, int linenum, 802 const char *ignored_unknown) 803 { 804 int i; 805 806 for (i = 0; keywords[i].name; i++) 807 if (strcmp(cp, keywords[i].name) == 0) 808 return keywords[i].opcode; 809 if (ignored_unknown != NULL && 810 match_pattern_list(cp, ignored_unknown, 1) == 1) 811 return oIgnoredUnknownOption; 812 error("%s: line %d: Bad configuration option: %s", 813 filename, linenum, cp); 814 return oBadOption; 815 } 816 817 /* Multistate option parsing */ 818 struct multistate { 819 const char *key; 820 int value; 821 }; 822 static const struct multistate multistate_flag[] = { 823 { "true", 1 }, 824 { "false", 0 }, 825 { "yes", 1 }, 826 { "no", 0 }, 827 { NULL, -1 } 828 }; 829 static const struct multistate multistate_yesnoask[] = { 830 { "true", 1 }, 831 { "false", 0 }, 832 { "yes", 1 }, 833 { "no", 0 }, 834 { "ask", 2 }, 835 { NULL, -1 } 836 }; 837 static const struct multistate multistate_strict_hostkey[] = { 838 { "true", SSH_STRICT_HOSTKEY_YES }, 839 { "false", SSH_STRICT_HOSTKEY_OFF }, 840 { "yes", SSH_STRICT_HOSTKEY_YES }, 841 { "no", SSH_STRICT_HOSTKEY_OFF }, 842 { "ask", SSH_STRICT_HOSTKEY_ASK }, 843 { "off", SSH_STRICT_HOSTKEY_OFF }, 844 { "accept-new", SSH_STRICT_HOSTKEY_NEW }, 845 { NULL, -1 } 846 }; 847 static const struct multistate multistate_yesnoaskconfirm[] = { 848 { "true", 1 }, 849 { "false", 0 }, 850 { "yes", 1 }, 851 { "no", 0 }, 852 { "ask", 2 }, 853 { "confirm", 3 }, 854 { NULL, -1 } 855 }; 856 static const struct multistate multistate_addressfamily[] = { 857 { "inet", AF_INET }, 858 { "inet6", AF_INET6 }, 859 { "any", AF_UNSPEC }, 860 { NULL, -1 } 861 }; 862 static const struct multistate multistate_controlmaster[] = { 863 { "true", SSHCTL_MASTER_YES }, 864 { "yes", SSHCTL_MASTER_YES }, 865 { "false", SSHCTL_MASTER_NO }, 866 { "no", SSHCTL_MASTER_NO }, 867 { "auto", SSHCTL_MASTER_AUTO }, 868 { "ask", SSHCTL_MASTER_ASK }, 869 { "autoask", SSHCTL_MASTER_AUTO_ASK }, 870 { NULL, -1 } 871 }; 872 static const struct multistate multistate_tunnel[] = { 873 { "ethernet", SSH_TUNMODE_ETHERNET }, 874 { "point-to-point", SSH_TUNMODE_POINTOPOINT }, 875 { "true", SSH_TUNMODE_DEFAULT }, 876 { "yes", SSH_TUNMODE_DEFAULT }, 877 { "false", SSH_TUNMODE_NO }, 878 { "no", SSH_TUNMODE_NO }, 879 { NULL, -1 } 880 }; 881 static const struct multistate multistate_requesttty[] = { 882 { "true", REQUEST_TTY_YES }, 883 { "yes", REQUEST_TTY_YES }, 884 { "false", REQUEST_TTY_NO }, 885 { "no", REQUEST_TTY_NO }, 886 { "force", REQUEST_TTY_FORCE }, 887 { "auto", REQUEST_TTY_AUTO }, 888 { NULL, -1 } 889 }; 890 static const struct multistate multistate_canonicalizehostname[] = { 891 { "true", SSH_CANONICALISE_YES }, 892 { "false", SSH_CANONICALISE_NO }, 893 { "yes", SSH_CANONICALISE_YES }, 894 { "no", SSH_CANONICALISE_NO }, 895 { "always", SSH_CANONICALISE_ALWAYS }, 896 { NULL, -1 } 897 }; 898 static const struct multistate multistate_compression[] = { 899 #ifdef WITH_ZLIB 900 { "yes", COMP_ZLIB }, 901 #endif 902 { "no", COMP_NONE }, 903 { NULL, -1 } 904 }; 905 906 /* 907 * Processes a single option line as used in the configuration files. This 908 * only sets those values that have not already been set. 909 */ 910 int 911 process_config_line(Options *options, struct passwd *pw, const char *host, 912 const char *original_host, char *line, const char *filename, 913 int linenum, int *activep, int flags) 914 { 915 return process_config_line_depth(options, pw, host, original_host, 916 line, filename, linenum, activep, flags, NULL, 0); 917 } 918 919 #define WHITESPACE " \t\r\n" 920 static int 921 process_config_line_depth(Options *options, struct passwd *pw, const char *host, 922 const char *original_host, char *line, const char *filename, 923 int linenum, int *activep, int flags, int *want_final_pass, int depth) 924 { 925 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; 926 char **cpptr, fwdarg[256]; 927 u_int i, *uintptr, max_entries = 0; 928 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0; 929 int remotefwd, dynamicfwd; 930 LogLevel *log_level_ptr; 931 SyslogFacility *log_facility_ptr; 932 long long val64; 933 size_t len; 934 struct Forward fwd; 935 const struct multistate *multistate_ptr; 936 struct allowed_cname *cname; 937 glob_t gl; 938 const char *errstr; 939 940 if (activep == NULL) { /* We are processing a command line directive */ 941 cmdline = 1; 942 activep = &cmdline; 943 } 944 945 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ 946 if ((len = strlen(line)) == 0) 947 return 0; 948 for (len--; len > 0; len--) { 949 if (strchr(WHITESPACE "\f", line[len]) == NULL) 950 break; 951 line[len] = '\0'; 952 } 953 954 s = line; 955 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 956 if ((keyword = strdelim(&s)) == NULL) 957 return 0; 958 /* Ignore leading whitespace. */ 959 if (*keyword == '\0') 960 keyword = strdelim(&s); 961 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 962 return 0; 963 /* Match lowercase keyword */ 964 lowercase(keyword); 965 966 opcode = parse_token(keyword, filename, linenum, 967 options->ignored_unknown); 968 969 switch (opcode) { 970 case oBadOption: 971 /* don't panic, but count bad options */ 972 return -1; 973 case oIgnore: 974 return 0; 975 case oIgnoredUnknownOption: 976 debug("%s line %d: Ignored unknown option \"%s\"", 977 filename, linenum, keyword); 978 return 0; 979 case oConnectTimeout: 980 intptr = &options->connection_timeout; 981 parse_time: 982 arg = strdelim(&s); 983 if (!arg || *arg == '\0') 984 fatal("%s line %d: missing time value.", 985 filename, linenum); 986 if (strcmp(arg, "none") == 0) 987 value = -1; 988 else if ((value = convtime(arg)) == -1) 989 fatal("%s line %d: invalid time value.", 990 filename, linenum); 991 if (*activep && *intptr == -1) 992 *intptr = value; 993 break; 994 995 case oForwardAgent: 996 intptr = &options->forward_agent; 997 998 arg = strdelim(&s); 999 if (!arg || *arg == '\0') 1000 fatal("%s line %d: missing argument.", 1001 filename, linenum); 1002 1003 value = -1; 1004 multistate_ptr = multistate_flag; 1005 for (i = 0; multistate_ptr[i].key != NULL; i++) { 1006 if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 1007 value = multistate_ptr[i].value; 1008 break; 1009 } 1010 } 1011 if (value != -1) { 1012 if (*activep && *intptr == -1) 1013 *intptr = value; 1014 break; 1015 } 1016 /* ForwardAgent wasn't 'yes' or 'no', assume a path */ 1017 if (*activep && *intptr == -1) 1018 *intptr = 1; 1019 1020 charptr = &options->forward_agent_sock_path; 1021 goto parse_agent_path; 1022 1023 case oForwardX11: 1024 intptr = &options->forward_x11; 1025 parse_flag: 1026 multistate_ptr = multistate_flag; 1027 parse_multistate: 1028 arg = strdelim(&s); 1029 if (!arg || *arg == '\0') 1030 fatal("%s line %d: missing argument.", 1031 filename, linenum); 1032 value = -1; 1033 for (i = 0; multistate_ptr[i].key != NULL; i++) { 1034 if (strcasecmp(arg, multistate_ptr[i].key) == 0) { 1035 value = multistate_ptr[i].value; 1036 break; 1037 } 1038 } 1039 if (value == -1) 1040 fatal("%s line %d: unsupported option \"%s\".", 1041 filename, linenum, arg); 1042 if (*activep && *intptr == -1) 1043 *intptr = value; 1044 break; 1045 1046 case oForwardX11Trusted: 1047 intptr = &options->forward_x11_trusted; 1048 goto parse_flag; 1049 1050 case oForwardX11Timeout: 1051 intptr = &options->forward_x11_timeout; 1052 goto parse_time; 1053 1054 case oGatewayPorts: 1055 intptr = &options->fwd_opts.gateway_ports; 1056 goto parse_flag; 1057 1058 case oExitOnForwardFailure: 1059 intptr = &options->exit_on_forward_failure; 1060 goto parse_flag; 1061 1062 case oPasswordAuthentication: 1063 intptr = &options->password_authentication; 1064 goto parse_flag; 1065 1066 case oKbdInteractiveAuthentication: 1067 intptr = &options->kbd_interactive_authentication; 1068 goto parse_flag; 1069 1070 case oKbdInteractiveDevices: 1071 charptr = &options->kbd_interactive_devices; 1072 goto parse_string; 1073 1074 case oPubkeyAuthentication: 1075 intptr = &options->pubkey_authentication; 1076 goto parse_flag; 1077 1078 case oHostbasedAuthentication: 1079 intptr = &options->hostbased_authentication; 1080 goto parse_flag; 1081 1082 case oChallengeResponseAuthentication: 1083 intptr = &options->challenge_response_authentication; 1084 goto parse_flag; 1085 1086 #if defined(KRB4) || defined(KRB5) 1087 case oKerberosAuthentication: 1088 intptr = &options->kerberos_authentication; 1089 goto parse_flag; 1090 #endif 1091 #if defined(AFS) || defined(KRB5) 1092 case oKerberosTgtPassing: 1093 intptr = &options->kerberos_tgt_passing; 1094 goto parse_flag; 1095 #endif 1096 1097 case oGssAuthentication: 1098 intptr = &options->gss_authentication; 1099 goto parse_flag; 1100 1101 #ifdef AFS 1102 case oAFSTokenPassing: 1103 intptr = &options->afs_token_passing; 1104 goto parse_flag; 1105 #endif 1106 1107 case oGssDelegateCreds: 1108 intptr = &options->gss_deleg_creds; 1109 goto parse_flag; 1110 1111 case oBatchMode: 1112 intptr = &options->batch_mode; 1113 goto parse_flag; 1114 1115 case oCheckHostIP: 1116 intptr = &options->check_host_ip; 1117 goto parse_flag; 1118 1119 case oNoneEnabled: 1120 intptr = &options->none_enabled; 1121 goto parse_flag; 1122 1123 /* we check to see if the command comes from the */ 1124 /* command line or not. If it does then enable it */ 1125 /* otherwise fail. NONE should never be a default configuration */ 1126 case oNoneSwitch: 1127 if(strcmp(filename,"command-line")==0) 1128 { 1129 intptr = &options->none_switch; 1130 goto parse_flag; 1131 } else { 1132 error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename); 1133 error("Continuing..."); 1134 debug("NoneSwitch directive found in %.200s.", filename); 1135 return 0; 1136 } 1137 1138 case oHPNDisabled: 1139 intptr = &options->hpn_disabled; 1140 goto parse_flag; 1141 1142 case oHPNBufferSize: 1143 intptr = &options->hpn_buffer_size; 1144 goto parse_int; 1145 1146 case oTcpRcvBufPoll: 1147 intptr = &options->tcp_rcv_buf_poll; 1148 goto parse_flag; 1149 1150 case oVerifyHostKeyDNS: 1151 intptr = &options->verify_host_key_dns; 1152 multistate_ptr = multistate_yesnoask; 1153 goto parse_multistate; 1154 1155 case oStrictHostKeyChecking: 1156 intptr = &options->strict_host_key_checking; 1157 multistate_ptr = multistate_strict_hostkey; 1158 goto parse_multistate; 1159 1160 case oCompression: 1161 intptr = &options->compression; 1162 multistate_ptr = multistate_compression; 1163 goto parse_multistate; 1164 1165 case oTCPKeepAlive: 1166 intptr = &options->tcp_keep_alive; 1167 goto parse_flag; 1168 1169 case oNoHostAuthenticationForLocalhost: 1170 intptr = &options->no_host_authentication_for_localhost; 1171 goto parse_flag; 1172 1173 case oNumberOfPasswordPrompts: 1174 intptr = &options->number_of_password_prompts; 1175 goto parse_int; 1176 1177 case oRekeyLimit: 1178 arg = strdelim(&s); 1179 if (!arg || *arg == '\0') 1180 fatal("%.200s line %d: Missing argument.", filename, 1181 linenum); 1182 if (strcmp(arg, "default") == 0) { 1183 val64 = 0; 1184 } else { 1185 if (scan_scaled(arg, &val64) == -1) 1186 fatal("%.200s line %d: Bad number '%s': %s", 1187 filename, linenum, arg, strerror(errno)); 1188 if (val64 != 0 && val64 < 16) 1189 fatal("%.200s line %d: RekeyLimit too small", 1190 filename, linenum); 1191 } 1192 if (*activep && options->rekey_limit == -1) 1193 options->rekey_limit = val64; 1194 if (s != NULL) { /* optional rekey interval present */ 1195 if (strcmp(s, "none") == 0) { 1196 (void)strdelim(&s); /* discard */ 1197 break; 1198 } 1199 intptr = &options->rekey_interval; 1200 goto parse_time; 1201 } 1202 break; 1203 1204 case oIdentityFile: 1205 arg = strdelim(&s); 1206 if (!arg || *arg == '\0') 1207 fatal("%.200s line %d: Missing argument.", filename, linenum); 1208 if (*activep) { 1209 intptr = &options->num_identity_files; 1210 if (*intptr >= SSH_MAX_IDENTITY_FILES) 1211 fatal("%.200s line %d: Too many identity files specified (max %d).", 1212 filename, linenum, SSH_MAX_IDENTITY_FILES); 1213 add_identity_file(options, NULL, 1214 arg, flags & SSHCONF_USERCONF); 1215 } 1216 break; 1217 1218 case oCertificateFile: 1219 arg = strdelim(&s); 1220 if (!arg || *arg == '\0') 1221 fatal("%.200s line %d: Missing argument.", 1222 filename, linenum); 1223 if (*activep) { 1224 intptr = &options->num_certificate_files; 1225 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) { 1226 fatal("%.200s line %d: Too many certificate " 1227 "files specified (max %d).", 1228 filename, linenum, 1229 SSH_MAX_CERTIFICATE_FILES); 1230 } 1231 add_certificate_file(options, arg, 1232 flags & SSHCONF_USERCONF); 1233 } 1234 break; 1235 1236 case oXAuthLocation: 1237 charptr=&options->xauth_location; 1238 goto parse_string; 1239 1240 case oUser: 1241 charptr = &options->user; 1242 parse_string: 1243 arg = strdelim(&s); 1244 if (!arg || *arg == '\0') 1245 fatal("%.200s line %d: Missing argument.", 1246 filename, linenum); 1247 if (*activep && *charptr == NULL) 1248 *charptr = xstrdup(arg); 1249 break; 1250 1251 case oGlobalKnownHostsFile: 1252 cpptr = (char **)&options->system_hostfiles; 1253 uintptr = &options->num_system_hostfiles; 1254 max_entries = SSH_MAX_HOSTS_FILES; 1255 parse_char_array: 1256 if (*activep && *uintptr == 0) { 1257 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1258 if ((*uintptr) >= max_entries) 1259 fatal("%s line %d: " 1260 "too many known hosts files.", 1261 filename, linenum); 1262 cpptr[(*uintptr)++] = xstrdup(arg); 1263 } 1264 } 1265 return 0; 1266 1267 case oUserKnownHostsFile: 1268 cpptr = (char **)&options->user_hostfiles; 1269 uintptr = &options->num_user_hostfiles; 1270 max_entries = SSH_MAX_HOSTS_FILES; 1271 goto parse_char_array; 1272 1273 case oHostname: 1274 charptr = &options->hostname; 1275 goto parse_string; 1276 1277 case oHostKeyAlias: 1278 charptr = &options->host_key_alias; 1279 goto parse_string; 1280 1281 case oPreferredAuthentications: 1282 charptr = &options->preferred_authentications; 1283 goto parse_string; 1284 1285 case oBindAddress: 1286 charptr = &options->bind_address; 1287 goto parse_string; 1288 1289 case oBindInterface: 1290 charptr = &options->bind_interface; 1291 goto parse_string; 1292 1293 case oPKCS11Provider: 1294 charptr = &options->pkcs11_provider; 1295 goto parse_string; 1296 1297 case oSecurityKeyProvider: 1298 charptr = &options->sk_provider; 1299 goto parse_string; 1300 1301 case oProxyCommand: 1302 charptr = &options->proxy_command; 1303 /* Ignore ProxyCommand if ProxyJump already specified */ 1304 if (options->jump_host != NULL) 1305 charptr = &options->jump_host; /* Skip below */ 1306 parse_command: 1307 if (s == NULL) 1308 fatal("%.200s line %d: Missing argument.", filename, linenum); 1309 len = strspn(s, WHITESPACE "="); 1310 if (*activep && *charptr == NULL) 1311 *charptr = xstrdup(s + len); 1312 return 0; 1313 1314 case oProxyJump: 1315 if (s == NULL) { 1316 fatal("%.200s line %d: Missing argument.", 1317 filename, linenum); 1318 } 1319 len = strspn(s, WHITESPACE "="); 1320 if (parse_jump(s + len, options, *activep) == -1) { 1321 fatal("%.200s line %d: Invalid ProxyJump \"%s\"", 1322 filename, linenum, s + len); 1323 } 1324 return 0; 1325 1326 case oPort: 1327 arg = strdelim(&s); 1328 if (!arg || *arg == '\0') 1329 fatal("%.200s line %d: Missing argument.", 1330 filename, linenum); 1331 value = a2port(arg); 1332 if (value <= 0) 1333 fatal("%.200s line %d: Bad port '%s'.", 1334 filename, linenum, arg); 1335 if (*activep && options->port == -1) 1336 options->port = value; 1337 break; 1338 1339 case oConnectionAttempts: 1340 intptr = &options->connection_attempts; 1341 parse_int: 1342 arg = strdelim(&s); 1343 if ((errstr = atoi_err(arg, &value)) != NULL) 1344 fatal("%s line %d: integer value %s.", 1345 filename, linenum, errstr); 1346 if (*activep && *intptr == -1) 1347 *intptr = value; 1348 break; 1349 1350 case oTcpRcvBuf: 1351 intptr = &options->tcp_rcv_buf; 1352 goto parse_int; 1353 1354 case oCiphers: 1355 arg = strdelim(&s); 1356 if (!arg || *arg == '\0') 1357 fatal("%.200s line %d: Missing argument.", filename, linenum); 1358 if (*arg != '-' && 1359 !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) 1360 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 1361 filename, linenum, arg ? arg : "<NONE>"); 1362 if (*activep && options->ciphers == NULL) 1363 options->ciphers = xstrdup(arg); 1364 break; 1365 1366 case oMacs: 1367 arg = strdelim(&s); 1368 if (!arg || *arg == '\0') 1369 fatal("%.200s line %d: Missing argument.", filename, linenum); 1370 if (*arg != '-' && 1371 !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) 1372 fatal("%.200s line %d: Bad SSH2 MAC spec '%s'.", 1373 filename, linenum, arg ? arg : "<NONE>"); 1374 if (*activep && options->macs == NULL) 1375 options->macs = xstrdup(arg); 1376 break; 1377 1378 case oKexAlgorithms: 1379 arg = strdelim(&s); 1380 if (!arg || *arg == '\0') 1381 fatal("%.200s line %d: Missing argument.", 1382 filename, linenum); 1383 if (*arg != '-' && 1384 !kex_names_valid(*arg == '+' || *arg == '^' ? 1385 arg + 1 : arg)) 1386 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", 1387 filename, linenum, arg ? arg : "<NONE>"); 1388 if (*activep && options->kex_algorithms == NULL) 1389 options->kex_algorithms = xstrdup(arg); 1390 break; 1391 1392 case oHostKeyAlgorithms: 1393 charptr = &options->hostkeyalgorithms; 1394 parse_keytypes: 1395 arg = strdelim(&s); 1396 if (!arg || *arg == '\0') 1397 fatal("%.200s line %d: Missing argument.", 1398 filename, linenum); 1399 if (*arg != '-' && 1400 !sshkey_names_valid2(*arg == '+' || *arg == '^' ? 1401 arg + 1 : arg, 1)) 1402 fatal("%s line %d: Bad key types '%s'.", 1403 filename, linenum, arg ? arg : "<NONE>"); 1404 if (*activep && *charptr == NULL) 1405 *charptr = xstrdup(arg); 1406 break; 1407 1408 case oCASignatureAlgorithms: 1409 charptr = &options->ca_sign_algorithms; 1410 goto parse_keytypes; 1411 1412 case oLogLevel: 1413 log_level_ptr = &options->log_level; 1414 arg = strdelim(&s); 1415 value = log_level_number(arg); 1416 if (value == SYSLOG_LEVEL_NOT_SET) 1417 fatal("%.200s line %d: unsupported log level '%s'", 1418 filename, linenum, arg ? arg : "<NONE>"); 1419 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 1420 *log_level_ptr = (LogLevel) value; 1421 break; 1422 1423 case oLogFacility: 1424 log_facility_ptr = &options->log_facility; 1425 arg = strdelim(&s); 1426 value = log_facility_number(arg); 1427 if (value == SYSLOG_FACILITY_NOT_SET) 1428 fatal("%.200s line %d: unsupported log facility '%s'", 1429 filename, linenum, arg ? arg : "<NONE>"); 1430 if (*log_facility_ptr == -1) 1431 *log_facility_ptr = (SyslogFacility) value; 1432 break; 1433 1434 case oLocalForward: 1435 case oRemoteForward: 1436 case oDynamicForward: 1437 arg = strdelim(&s); 1438 if (arg == NULL || *arg == '\0') 1439 fatal("%.200s line %d: Missing port argument.", 1440 filename, linenum); 1441 1442 remotefwd = (opcode == oRemoteForward); 1443 dynamicfwd = (opcode == oDynamicForward); 1444 1445 if (!dynamicfwd) { 1446 arg2 = strdelim(&s); 1447 if (arg2 == NULL || *arg2 == '\0') { 1448 if (remotefwd) 1449 dynamicfwd = 1; 1450 else 1451 fatal("%.200s line %d: Missing target " 1452 "argument.", filename, linenum); 1453 } else { 1454 /* construct a string for parse_forward */ 1455 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, 1456 arg2); 1457 } 1458 } 1459 if (dynamicfwd) 1460 strlcpy(fwdarg, arg, sizeof(fwdarg)); 1461 1462 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) 1463 fatal("%.200s line %d: Bad forwarding specification.", 1464 filename, linenum); 1465 1466 if (*activep) { 1467 if (remotefwd) { 1468 add_remote_forward(options, &fwd); 1469 } else { 1470 add_local_forward(options, &fwd); 1471 } 1472 } 1473 break; 1474 1475 case oClearAllForwardings: 1476 intptr = &options->clear_forwardings; 1477 goto parse_flag; 1478 1479 case oHost: 1480 if (cmdline) 1481 fatal("Host directive not supported as a command-line " 1482 "option"); 1483 *activep = 0; 1484 arg2 = NULL; 1485 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1486 if ((flags & SSHCONF_NEVERMATCH) != 0) 1487 break; 1488 negated = *arg == '!'; 1489 if (negated) 1490 arg++; 1491 if (match_pattern(host, arg)) { 1492 if (negated) { 1493 debug("%.200s line %d: Skipping Host " 1494 "block because of negated match " 1495 "for %.100s", filename, linenum, 1496 arg); 1497 *activep = 0; 1498 break; 1499 } 1500 if (!*activep) 1501 arg2 = arg; /* logged below */ 1502 *activep = 1; 1503 } 1504 } 1505 if (*activep) 1506 debug("%.200s line %d: Applying options for %.100s", 1507 filename, linenum, arg2); 1508 /* Avoid garbage check below, as strdelim is done. */ 1509 return 0; 1510 1511 case oMatch: 1512 if (cmdline) 1513 fatal("Host directive not supported as a command-line " 1514 "option"); 1515 value = match_cfg_line(options, &s, pw, host, original_host, 1516 flags & SSHCONF_FINAL, want_final_pass, 1517 filename, linenum); 1518 if (value < 0) 1519 fatal("%.200s line %d: Bad Match condition", filename, 1520 linenum); 1521 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value; 1522 break; 1523 1524 case oEscapeChar: 1525 intptr = &options->escape_char; 1526 arg = strdelim(&s); 1527 if (!arg || *arg == '\0') 1528 fatal("%.200s line %d: Missing argument.", filename, linenum); 1529 value = 0; /* To avoid compiler warning... */ 1530 if (strcmp(arg, "none") == 0) 1531 value = SSH_ESCAPECHAR_NONE; 1532 else if (arg[1] == '\0') 1533 value = (u_char) arg[0]; 1534 else if (arg[0] == '^' && arg[2] == 0 && 1535 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 1536 value = (u_char) arg[1] & 31; 1537 else { 1538 fatal("%.200s line %d: Bad escape character.", 1539 filename, linenum); 1540 /* NOTREACHED */ 1541 value = 0; /* Avoid compiler warning. */ 1542 } 1543 if (*activep && *intptr == -1) 1544 *intptr = value; 1545 break; 1546 1547 case oAddressFamily: 1548 intptr = &options->address_family; 1549 multistate_ptr = multistate_addressfamily; 1550 goto parse_multistate; 1551 1552 case oEnableSSHKeysign: 1553 intptr = &options->enable_ssh_keysign; 1554 goto parse_flag; 1555 1556 case oIdentitiesOnly: 1557 intptr = &options->identities_only; 1558 goto parse_flag; 1559 1560 case oServerAliveInterval: 1561 intptr = &options->server_alive_interval; 1562 goto parse_time; 1563 1564 case oServerAliveCountMax: 1565 intptr = &options->server_alive_count_max; 1566 goto parse_int; 1567 1568 case oSendEnv: 1569 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1570 if (strchr(arg, '=') != NULL) 1571 fatal("%s line %d: Invalid environment name.", 1572 filename, linenum); 1573 if (!*activep) 1574 continue; 1575 if (*arg == '-') { 1576 /* Removing an env var */ 1577 rm_env(options, arg, filename, linenum); 1578 continue; 1579 } else { 1580 /* Adding an env var */ 1581 if (options->num_send_env >= INT_MAX) 1582 fatal("%s line %d: too many send env.", 1583 filename, linenum); 1584 options->send_env = xrecallocarray( 1585 options->send_env, options->num_send_env, 1586 options->num_send_env + 1, 1587 sizeof(*options->send_env)); 1588 options->send_env[options->num_send_env++] = 1589 xstrdup(arg); 1590 } 1591 } 1592 break; 1593 1594 case oSetEnv: 1595 value = options->num_setenv; 1596 while ((arg = strdelimw(&s)) != NULL && *arg != '\0') { 1597 if (strchr(arg, '=') == NULL) 1598 fatal("%s line %d: Invalid SetEnv.", 1599 filename, linenum); 1600 if (!*activep || value != 0) 1601 continue; 1602 /* Adding a setenv var */ 1603 if (options->num_setenv >= INT_MAX) 1604 fatal("%s line %d: too many SetEnv.", 1605 filename, linenum); 1606 options->setenv = xrecallocarray( 1607 options->setenv, options->num_setenv, 1608 options->num_setenv + 1, sizeof(*options->setenv)); 1609 options->setenv[options->num_setenv++] = xstrdup(arg); 1610 } 1611 break; 1612 1613 case oControlPath: 1614 charptr = &options->control_path; 1615 goto parse_string; 1616 1617 case oControlMaster: 1618 intptr = &options->control_master; 1619 multistate_ptr = multistate_controlmaster; 1620 goto parse_multistate; 1621 1622 case oControlPersist: 1623 /* no/false/yes/true, or a time spec */ 1624 intptr = &options->control_persist; 1625 arg = strdelim(&s); 1626 if (!arg || *arg == '\0') 1627 fatal("%.200s line %d: Missing ControlPersist" 1628 " argument.", filename, linenum); 1629 value = 0; 1630 value2 = 0; /* timeout */ 1631 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 1632 value = 0; 1633 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 1634 value = 1; 1635 else if ((value2 = convtime(arg)) >= 0) 1636 value = 1; 1637 else 1638 fatal("%.200s line %d: Bad ControlPersist argument.", 1639 filename, linenum); 1640 if (*activep && *intptr == -1) { 1641 *intptr = value; 1642 options->control_persist_timeout = value2; 1643 } 1644 break; 1645 1646 case oHashKnownHosts: 1647 intptr = &options->hash_known_hosts; 1648 goto parse_flag; 1649 1650 case oTunnel: 1651 intptr = &options->tun_open; 1652 multistate_ptr = multistate_tunnel; 1653 goto parse_multistate; 1654 1655 case oTunnelDevice: 1656 arg = strdelim(&s); 1657 if (!arg || *arg == '\0') 1658 fatal("%.200s line %d: Missing argument.", filename, linenum); 1659 value = a2tun(arg, &value2); 1660 if (value == SSH_TUNID_ERR) 1661 fatal("%.200s line %d: Bad tun device.", filename, linenum); 1662 if (*activep) { 1663 options->tun_local = value; 1664 options->tun_remote = value2; 1665 } 1666 break; 1667 1668 case oLocalCommand: 1669 charptr = &options->local_command; 1670 goto parse_command; 1671 1672 case oPermitLocalCommand: 1673 intptr = &options->permit_local_command; 1674 goto parse_flag; 1675 1676 case oRemoteCommand: 1677 charptr = &options->remote_command; 1678 goto parse_command; 1679 1680 case oVisualHostKey: 1681 intptr = &options->visual_host_key; 1682 goto parse_flag; 1683 1684 case oInclude: 1685 if (cmdline) 1686 fatal("Include directive not supported as a " 1687 "command-line option"); 1688 value = 0; 1689 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1690 /* 1691 * Ensure all paths are anchored. User configuration 1692 * files may begin with '~/' but system configurations 1693 * must not. If the path is relative, then treat it 1694 * as living in ~/.ssh for user configurations or 1695 * /etc/ssh for system ones. 1696 */ 1697 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) 1698 fatal("%.200s line %d: bad include path %s.", 1699 filename, linenum, arg); 1700 if (!path_absolute(arg) && *arg != '~') { 1701 xasprintf(&arg2, "%s/%s", 1702 (flags & SSHCONF_USERCONF) ? 1703 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg); 1704 } else 1705 arg2 = xstrdup(arg); 1706 memset(&gl, 0, sizeof(gl)); 1707 r = glob(arg2, GLOB_TILDE | GLOB_LIMIT, NULL, &gl); 1708 if (r == GLOB_NOMATCH) { 1709 debug("%.200s line %d: include %s matched no " 1710 "files",filename, linenum, arg2); 1711 free(arg2); 1712 continue; 1713 } else if (r != 0) 1714 fatal("%.200s line %d: glob failed for %s.", 1715 filename, linenum, arg2); 1716 free(arg2); 1717 oactive = *activep; 1718 for (i = 0; i < gl.gl_pathc; i++) { 1719 debug3("%.200s line %d: Including file %s " 1720 "depth %d%s", filename, linenum, 1721 gl.gl_pathv[i], depth, 1722 oactive ? "" : " (parse only)"); 1723 r = read_config_file_depth(gl.gl_pathv[i], 1724 pw, host, original_host, options, 1725 flags | SSHCONF_CHECKPERM | 1726 (oactive ? 0 : SSHCONF_NEVERMATCH), 1727 activep, want_final_pass, depth + 1); 1728 if (r != 1 && errno != ENOENT) { 1729 fatal("Can't open user config file " 1730 "%.100s: %.100s", gl.gl_pathv[i], 1731 strerror(errno)); 1732 } 1733 /* 1734 * don't let Match in includes clobber the 1735 * containing file's Match state. 1736 */ 1737 *activep = oactive; 1738 if (r != 1) 1739 value = -1; 1740 } 1741 globfree(&gl); 1742 } 1743 if (value != 0) 1744 return value; 1745 break; 1746 1747 case oIPQoS: 1748 arg = strdelim(&s); 1749 if ((value = parse_ipqos(arg)) == -1) 1750 fatal("%s line %d: Bad IPQoS value: %s", 1751 filename, linenum, arg); 1752 arg = strdelim(&s); 1753 if (arg == NULL) 1754 value2 = value; 1755 else if ((value2 = parse_ipqos(arg)) == -1) 1756 fatal("%s line %d: Bad IPQoS value: %s", 1757 filename, linenum, arg); 1758 if (*activep) { 1759 options->ip_qos_interactive = value; 1760 options->ip_qos_bulk = value2; 1761 } 1762 break; 1763 1764 case oRequestTTY: 1765 intptr = &options->request_tty; 1766 multistate_ptr = multistate_requesttty; 1767 goto parse_multistate; 1768 1769 case oSendVersionFirst: 1770 intptr = &options->send_version_first; 1771 goto parse_flag; 1772 1773 case oIgnoreUnknown: 1774 charptr = &options->ignored_unknown; 1775 goto parse_string; 1776 1777 case oProxyUseFdpass: 1778 intptr = &options->proxy_use_fdpass; 1779 goto parse_flag; 1780 1781 case oCanonicalDomains: 1782 value = options->num_canonical_domains != 0; 1783 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1784 if (!valid_domain(arg, 1, &errstr)) { 1785 fatal("%s line %d: %s", filename, linenum, 1786 errstr); 1787 } 1788 if (!*activep || value) 1789 continue; 1790 if (options->num_canonical_domains >= MAX_CANON_DOMAINS) 1791 fatal("%s line %d: too many hostname suffixes.", 1792 filename, linenum); 1793 options->canonical_domains[ 1794 options->num_canonical_domains++] = xstrdup(arg); 1795 } 1796 break; 1797 1798 case oCanonicalizePermittedCNAMEs: 1799 value = options->num_permitted_cnames != 0; 1800 while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1801 /* Either '*' for everything or 'list:list' */ 1802 if (strcmp(arg, "*") == 0) 1803 arg2 = arg; 1804 else { 1805 lowercase(arg); 1806 if ((arg2 = strchr(arg, ':')) == NULL || 1807 arg2[1] == '\0') { 1808 fatal("%s line %d: " 1809 "Invalid permitted CNAME \"%s\"", 1810 filename, linenum, arg); 1811 } 1812 *arg2 = '\0'; 1813 arg2++; 1814 } 1815 if (!*activep || value) 1816 continue; 1817 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS) 1818 fatal("%s line %d: too many permitted CNAMEs.", 1819 filename, linenum); 1820 cname = options->permitted_cnames + 1821 options->num_permitted_cnames++; 1822 cname->source_list = xstrdup(arg); 1823 cname->target_list = xstrdup(arg2); 1824 } 1825 break; 1826 1827 case oCanonicalizeHostname: 1828 intptr = &options->canonicalize_hostname; 1829 multistate_ptr = multistate_canonicalizehostname; 1830 goto parse_multistate; 1831 1832 case oCanonicalizeMaxDots: 1833 intptr = &options->canonicalize_max_dots; 1834 goto parse_int; 1835 1836 case oCanonicalizeFallbackLocal: 1837 intptr = &options->canonicalize_fallback_local; 1838 goto parse_flag; 1839 1840 case oStreamLocalBindMask: 1841 arg = strdelim(&s); 1842 if (!arg || *arg == '\0') 1843 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum); 1844 /* Parse mode in octal format */ 1845 value = strtol(arg, &endofnumber, 8); 1846 if (arg == endofnumber || value < 0 || value > 0777) 1847 fatal("%.200s line %d: Bad mask.", filename, linenum); 1848 options->fwd_opts.streamlocal_bind_mask = (mode_t)value; 1849 break; 1850 1851 case oStreamLocalBindUnlink: 1852 intptr = &options->fwd_opts.streamlocal_bind_unlink; 1853 goto parse_flag; 1854 1855 case oRevokedHostKeys: 1856 charptr = &options->revoked_host_keys; 1857 goto parse_string; 1858 1859 case oFingerprintHash: 1860 intptr = &options->fingerprint_hash; 1861 arg = strdelim(&s); 1862 if (!arg || *arg == '\0') 1863 fatal("%.200s line %d: Missing argument.", 1864 filename, linenum); 1865 if ((value = ssh_digest_alg_by_name(arg)) == -1) 1866 fatal("%.200s line %d: Invalid hash algorithm \"%s\".", 1867 filename, linenum, arg); 1868 if (*activep && *intptr == -1) 1869 *intptr = value; 1870 break; 1871 1872 case oUpdateHostkeys: 1873 intptr = &options->update_hostkeys; 1874 multistate_ptr = multistate_yesnoask; 1875 goto parse_multistate; 1876 1877 case oHostbasedKeyTypes: 1878 charptr = &options->hostbased_key_types; 1879 goto parse_keytypes; 1880 1881 case oPubkeyAcceptedKeyTypes: 1882 charptr = &options->pubkey_key_types; 1883 goto parse_keytypes; 1884 1885 case oAddKeysToAgent: 1886 intptr = &options->add_keys_to_agent; 1887 multistate_ptr = multistate_yesnoaskconfirm; 1888 goto parse_multistate; 1889 1890 case oIdentityAgent: 1891 charptr = &options->identity_agent; 1892 arg = strdelim(&s); 1893 if (!arg || *arg == '\0') 1894 fatal("%.200s line %d: Missing argument.", 1895 filename, linenum); 1896 parse_agent_path: 1897 /* Extra validation if the string represents an env var. */ 1898 if (arg[0] == '$' && !valid_env_name(arg + 1)) { 1899 fatal("%.200s line %d: Invalid environment name %s.", 1900 filename, linenum, arg); 1901 } 1902 if (*activep && *charptr == NULL) 1903 *charptr = xstrdup(arg); 1904 break; 1905 1906 case oDeprecated: 1907 debug("%s line %d: Deprecated option \"%s\"", 1908 filename, linenum, keyword); 1909 return 0; 1910 1911 case oUnsupported: 1912 error("%s line %d: Unsupported option \"%s\"", 1913 filename, linenum, keyword); 1914 return 0; 1915 1916 default: 1917 fatal("%s: Unimplemented opcode %d", __func__, opcode); 1918 } 1919 1920 /* Check that there is no garbage at end of line. */ 1921 if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1922 fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 1923 filename, linenum, arg); 1924 } 1925 return 0; 1926 } 1927 1928 /* 1929 * Reads the config file and modifies the options accordingly. Options 1930 * should already be initialized before this call. This never returns if 1931 * there is an error. If the file does not exist, this returns 0. 1932 */ 1933 int 1934 read_config_file(const char *filename, struct passwd *pw, const char *host, 1935 const char *original_host, Options *options, int flags, 1936 int *want_final_pass) 1937 { 1938 int active = 1; 1939 1940 return read_config_file_depth(filename, pw, host, original_host, 1941 options, flags, &active, want_final_pass, 0); 1942 } 1943 1944 #define READCONF_MAX_DEPTH 16 1945 static int 1946 read_config_file_depth(const char *filename, struct passwd *pw, 1947 const char *host, const char *original_host, Options *options, 1948 int flags, int *activep, int *want_final_pass, int depth) 1949 { 1950 FILE *f; 1951 char *line = NULL; 1952 size_t linesize = 0; 1953 int linenum; 1954 int bad_options = 0; 1955 1956 if (depth < 0 || depth > READCONF_MAX_DEPTH) 1957 fatal("Too many recursive configuration includes"); 1958 1959 if ((f = fopen(filename, "r")) == NULL) 1960 return 0; 1961 1962 if (flags & SSHCONF_CHECKPERM) { 1963 struct stat sb; 1964 1965 if (fstat(fileno(f), &sb) == -1) 1966 fatal("fstat %s: %s", filename, strerror(errno)); 1967 if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 1968 (sb.st_mode & 022) != 0)) 1969 fatal("Bad owner or permissions on %s", filename); 1970 } 1971 1972 debug("Reading configuration data %.200s", filename); 1973 1974 /* 1975 * Mark that we are now processing the options. This flag is turned 1976 * on/off by Host specifications. 1977 */ 1978 linenum = 0; 1979 while (getline(&line, &linesize, f) != -1) { 1980 /* Update line number counter. */ 1981 linenum++; 1982 if (process_config_line_depth(options, pw, host, original_host, 1983 line, filename, linenum, activep, flags, want_final_pass, 1984 depth) != 0) 1985 bad_options++; 1986 } 1987 free(line); 1988 fclose(f); 1989 if (bad_options > 0) 1990 fatal("%s: terminating, %d bad configuration options", 1991 filename, bad_options); 1992 return 1; 1993 } 1994 1995 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ 1996 int 1997 option_clear_or_none(const char *o) 1998 { 1999 return o == NULL || strcasecmp(o, "none") == 0; 2000 } 2001 2002 /* 2003 * Initializes options to special values that indicate that they have not yet 2004 * been set. Read_config_file will only set options with this value. Options 2005 * are processed in the following order: command line, user config file, 2006 * system config file. Last, fill_default_options is called. 2007 */ 2008 2009 void 2010 initialize_options(Options * options) 2011 { 2012 memset(options, 'X', sizeof(*options)); 2013 options->forward_agent = -1; 2014 options->forward_agent_sock_path = NULL; 2015 options->forward_x11 = -1; 2016 options->forward_x11_trusted = -1; 2017 options->forward_x11_timeout = -1; 2018 options->stdio_forward_host = NULL; 2019 options->stdio_forward_port = 0; 2020 options->clear_forwardings = -1; 2021 options->exit_on_forward_failure = -1; 2022 options->xauth_location = NULL; 2023 options->fwd_opts.gateway_ports = -1; 2024 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; 2025 options->fwd_opts.streamlocal_bind_unlink = -1; 2026 options->pubkey_authentication = -1; 2027 options->challenge_response_authentication = -1; 2028 #if defined(KRB4) || defined(KRB5) 2029 options->kerberos_authentication = -1; 2030 #endif 2031 #if defined(AFS) || defined(KRB5) 2032 options->kerberos_tgt_passing = -1; 2033 #endif 2034 #ifdef AFS 2035 options->afs_token_passing = -1; 2036 #endif 2037 options->gss_authentication = -1; 2038 options->gss_deleg_creds = -1; 2039 options->password_authentication = -1; 2040 options->kbd_interactive_authentication = -1; 2041 options->kbd_interactive_devices = NULL; 2042 options->hostbased_authentication = -1; 2043 options->batch_mode = -1; 2044 options->check_host_ip = -1; 2045 options->strict_host_key_checking = -1; 2046 options->compression = -1; 2047 options->tcp_keep_alive = -1; 2048 options->port = -1; 2049 options->address_family = -1; 2050 options->connection_attempts = -1; 2051 options->connection_timeout = -1; 2052 options->number_of_password_prompts = -1; 2053 options->ciphers = NULL; 2054 options->macs = NULL; 2055 options->kex_algorithms = NULL; 2056 options->hostkeyalgorithms = NULL; 2057 options->ca_sign_algorithms = NULL; 2058 options->num_identity_files = 0; 2059 options->num_certificate_files = 0; 2060 options->hostname = NULL; 2061 options->host_key_alias = NULL; 2062 options->proxy_command = NULL; 2063 options->jump_user = NULL; 2064 options->jump_host = NULL; 2065 options->jump_port = -1; 2066 options->jump_extra = NULL; 2067 options->user = NULL; 2068 options->escape_char = -1; 2069 options->num_system_hostfiles = 0; 2070 options->num_user_hostfiles = 0; 2071 options->local_forwards = NULL; 2072 options->num_local_forwards = 0; 2073 options->remote_forwards = NULL; 2074 options->num_remote_forwards = 0; 2075 options->log_facility = SYSLOG_FACILITY_NOT_SET; 2076 options->log_level = SYSLOG_LEVEL_NOT_SET; 2077 options->preferred_authentications = NULL; 2078 options->bind_address = NULL; 2079 options->bind_interface = NULL; 2080 options->pkcs11_provider = NULL; 2081 options->sk_provider = NULL; 2082 options->enable_ssh_keysign = - 1; 2083 options->no_host_authentication_for_localhost = - 1; 2084 options->identities_only = - 1; 2085 options->rekey_limit = - 1; 2086 options->rekey_interval = -1; 2087 options->verify_host_key_dns = -1; 2088 options->server_alive_interval = -1; 2089 options->server_alive_count_max = -1; 2090 options->send_env = NULL; 2091 options->num_send_env = 0; 2092 options->setenv = NULL; 2093 options->num_setenv = 0; 2094 options->control_path = NULL; 2095 options->control_master = -1; 2096 options->control_persist = -1; 2097 options->control_persist_timeout = 0; 2098 options->hash_known_hosts = -1; 2099 options->tun_open = -1; 2100 options->tun_local = -1; 2101 options->tun_remote = -1; 2102 options->local_command = NULL; 2103 options->permit_local_command = -1; 2104 options->remote_command = NULL; 2105 options->add_keys_to_agent = -1; 2106 options->identity_agent = NULL; 2107 options->visual_host_key = -1; 2108 options->ip_qos_interactive = -1; 2109 options->ip_qos_bulk = -1; 2110 options->request_tty = -1; 2111 options->proxy_use_fdpass = -1; 2112 options->ignored_unknown = NULL; 2113 options->num_canonical_domains = 0; 2114 options->num_permitted_cnames = 0; 2115 options->canonicalize_max_dots = -1; 2116 options->canonicalize_fallback_local = -1; 2117 options->canonicalize_hostname = -1; 2118 options->revoked_host_keys = NULL; 2119 options->fingerprint_hash = -1; 2120 options->update_hostkeys = -1; 2121 options->hostbased_key_types = NULL; 2122 options->pubkey_key_types = NULL; 2123 options->none_switch = -1; 2124 options->none_enabled = -1; 2125 options->hpn_disabled = -1; 2126 options->hpn_buffer_size = -1; 2127 options->tcp_rcv_buf_poll = -1; 2128 options->tcp_rcv_buf = -1; 2129 options->send_version_first = -1; 2130 } 2131 2132 /* 2133 * A petite version of fill_default_options() that just fills the options 2134 * needed for hostname canonicalization to proceed. 2135 */ 2136 void 2137 fill_default_options_for_canonicalization(Options *options) 2138 { 2139 if (options->canonicalize_max_dots == -1) 2140 options->canonicalize_max_dots = 1; 2141 if (options->canonicalize_fallback_local == -1) 2142 options->canonicalize_fallback_local = 1; 2143 if (options->canonicalize_hostname == -1) 2144 options->canonicalize_hostname = SSH_CANONICALISE_NO; 2145 } 2146 2147 /* 2148 * Called after processing other sources of option data, this fills those 2149 * options for which no value has been specified with their default values. 2150 */ 2151 void 2152 fill_default_options(Options * options) 2153 { 2154 char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig; 2155 char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig; 2156 int r; 2157 2158 if (options->forward_agent == -1) 2159 options->forward_agent = 0; 2160 if (options->forward_x11 == -1) 2161 options->forward_x11 = 0; 2162 if (options->forward_x11_trusted == -1) 2163 options->forward_x11_trusted = 0; 2164 if (options->forward_x11_timeout == -1) 2165 options->forward_x11_timeout = 1200; 2166 /* 2167 * stdio forwarding (-W) changes the default for these but we defer 2168 * setting the values so they can be overridden. 2169 */ 2170 if (options->exit_on_forward_failure == -1) 2171 options->exit_on_forward_failure = 2172 options->stdio_forward_host != NULL ? 1 : 0; 2173 if (options->clear_forwardings == -1) 2174 options->clear_forwardings = 2175 options->stdio_forward_host != NULL ? 1 : 0; 2176 if (options->clear_forwardings == 1) 2177 clear_forwardings(options); 2178 2179 if (options->xauth_location == NULL) 2180 options->xauth_location = __UNCONST(_PATH_XAUTH); 2181 if (options->fwd_opts.gateway_ports == -1) 2182 options->fwd_opts.gateway_ports = 0; 2183 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) 2184 options->fwd_opts.streamlocal_bind_mask = 0177; 2185 if (options->fwd_opts.streamlocal_bind_unlink == -1) 2186 options->fwd_opts.streamlocal_bind_unlink = 0; 2187 if (options->pubkey_authentication == -1) 2188 options->pubkey_authentication = 1; 2189 if (options->challenge_response_authentication == -1) 2190 options->challenge_response_authentication = 1; 2191 #if defined(KRB4) || defined(KRB5) 2192 if (options->kerberos_authentication == -1) 2193 options->kerberos_authentication = 1; 2194 #endif 2195 #if defined(AFS) || defined(KRB5) 2196 if (options->kerberos_tgt_passing == -1) 2197 options->kerberos_tgt_passing = 1; 2198 #endif 2199 #ifdef AFS 2200 if (options->afs_token_passing == -1) 2201 options->afs_token_passing = 1; 2202 #endif 2203 if (options->gss_authentication == -1) 2204 options->gss_authentication = 0; 2205 if (options->gss_deleg_creds == -1) 2206 options->gss_deleg_creds = 0; 2207 if (options->password_authentication == -1) 2208 options->password_authentication = 1; 2209 if (options->kbd_interactive_authentication == -1) 2210 options->kbd_interactive_authentication = 1; 2211 if (options->hostbased_authentication == -1) 2212 options->hostbased_authentication = 0; 2213 if (options->batch_mode == -1) 2214 options->batch_mode = 0; 2215 if (options->check_host_ip == -1) 2216 options->check_host_ip = 1; 2217 if (options->strict_host_key_checking == -1) 2218 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK; 2219 if (options->compression == -1) 2220 options->compression = 0; 2221 if (options->tcp_keep_alive == -1) 2222 options->tcp_keep_alive = 1; 2223 if (options->port == -1) 2224 options->port = 0; /* Filled in ssh_connect. */ 2225 if (options->address_family == -1) 2226 options->address_family = AF_UNSPEC; 2227 if (options->connection_attempts == -1) 2228 options->connection_attempts = 1; 2229 if (options->number_of_password_prompts == -1) 2230 options->number_of_password_prompts = 3; 2231 /* options->hostkeyalgorithms, default set in myproposals.h */ 2232 if (options->add_keys_to_agent == -1) 2233 options->add_keys_to_agent = 0; 2234 if (options->num_identity_files == 0) { 2235 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0); 2236 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0); 2237 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0); 2238 add_identity_file(options, "~/", 2239 _PATH_SSH_CLIENT_ID_ECDSA_SK, 0); 2240 add_identity_file(options, "~/", 2241 _PATH_SSH_CLIENT_ID_ED25519, 0); 2242 add_identity_file(options, "~/", 2243 _PATH_SSH_CLIENT_ID_ED25519_SK, 0); 2244 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0); 2245 } 2246 if (options->escape_char == -1) 2247 options->escape_char = '~'; 2248 if (options->num_system_hostfiles == 0) { 2249 options->system_hostfiles[options->num_system_hostfiles++] = 2250 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); 2251 options->system_hostfiles[options->num_system_hostfiles++] = 2252 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); 2253 } 2254 if (options->update_hostkeys == -1) 2255 options->update_hostkeys = SSH_UPDATE_HOSTKEYS_NO; 2256 if (options->num_user_hostfiles == 0) { 2257 options->user_hostfiles[options->num_user_hostfiles++] = 2258 xstrdup(_PATH_SSH_USER_HOSTFILE); 2259 options->user_hostfiles[options->num_user_hostfiles++] = 2260 xstrdup(_PATH_SSH_USER_HOSTFILE2); 2261 } 2262 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 2263 options->log_level = SYSLOG_LEVEL_INFO; 2264 if (options->log_facility == SYSLOG_FACILITY_NOT_SET) 2265 options->log_facility = SYSLOG_FACILITY_USER; 2266 if (options->no_host_authentication_for_localhost == - 1) 2267 options->no_host_authentication_for_localhost = 0; 2268 if (options->identities_only == -1) 2269 options->identities_only = 0; 2270 if (options->enable_ssh_keysign == -1) 2271 options->enable_ssh_keysign = 0; 2272 if (options->rekey_limit == -1) 2273 options->rekey_limit = 0; 2274 if (options->rekey_interval == -1) 2275 options->rekey_interval = 0; 2276 if (options->verify_host_key_dns == -1) 2277 options->verify_host_key_dns = 0; 2278 if (options->server_alive_interval == -1) 2279 options->server_alive_interval = 0; 2280 if (options->server_alive_count_max == -1) 2281 options->server_alive_count_max = 3; 2282 if (options->none_switch == -1) 2283 options->none_switch = 0; 2284 if (options->hpn_disabled == -1) 2285 options->hpn_disabled = 0; 2286 if (options->hpn_buffer_size > -1) 2287 { 2288 /* if a user tries to set the size to 0 set it to 1KB */ 2289 if (options->hpn_buffer_size == 0) 2290 options->hpn_buffer_size = 1024; 2291 /*limit the buffer to 64MB*/ 2292 if (options->hpn_buffer_size > 65536) 2293 { 2294 options->hpn_buffer_size = 65536*1024; 2295 debug("User requested buffer larger than 64MB. Request reverted to 64MB"); 2296 } 2297 debug("hpn_buffer_size set to %d", options->hpn_buffer_size); 2298 } 2299 if (options->tcp_rcv_buf == 0) 2300 options->tcp_rcv_buf = 1; 2301 if (options->tcp_rcv_buf > -1) 2302 options->tcp_rcv_buf *=1024; 2303 if (options->tcp_rcv_buf_poll == -1) 2304 options->tcp_rcv_buf_poll = 1; 2305 if (options->control_master == -1) 2306 options->control_master = 0; 2307 if (options->control_persist == -1) { 2308 options->control_persist = 0; 2309 options->control_persist_timeout = 0; 2310 } 2311 if (options->hash_known_hosts == -1) 2312 options->hash_known_hosts = 0; 2313 if (options->tun_open == -1) 2314 options->tun_open = SSH_TUNMODE_NO; 2315 if (options->tun_local == -1) 2316 options->tun_local = SSH_TUNID_ANY; 2317 if (options->tun_remote == -1) 2318 options->tun_remote = SSH_TUNID_ANY; 2319 if (options->permit_local_command == -1) 2320 options->permit_local_command = 0; 2321 if (options->visual_host_key == -1) 2322 options->visual_host_key = 0; 2323 if (options->ip_qos_interactive == -1) 2324 options->ip_qos_interactive = IPTOS_DSCP_AF21; 2325 if (options->ip_qos_bulk == -1) 2326 options->ip_qos_bulk = IPTOS_DSCP_CS1; 2327 if (options->request_tty == -1) 2328 options->request_tty = REQUEST_TTY_AUTO; 2329 if (options->proxy_use_fdpass == -1) 2330 options->proxy_use_fdpass = 0; 2331 if (options->canonicalize_max_dots == -1) 2332 options->canonicalize_max_dots = 1; 2333 if (options->canonicalize_fallback_local == -1) 2334 options->canonicalize_fallback_local = 1; 2335 if (options->canonicalize_hostname == -1) 2336 options->canonicalize_hostname = SSH_CANONICALISE_NO; 2337 if (options->fingerprint_hash == -1) 2338 options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 2339 if (options->sk_provider == NULL) 2340 options->sk_provider = xstrdup("internal"); 2341 2342 /* Expand KEX name lists */ 2343 all_cipher = cipher_alg_list(',', 0); 2344 all_mac = mac_alg_list(','); 2345 all_kex = kex_alg_list(','); 2346 all_key = sshkey_alg_list(0, 0, 1, ','); 2347 all_sig = sshkey_alg_list(0, 1, 1, ','); 2348 /* remove unsupported algos from default lists */ 2349 def_cipher = match_filter_whitelist(KEX_CLIENT_ENCRYPT, all_cipher); 2350 def_mac = match_filter_whitelist(KEX_CLIENT_MAC, all_mac); 2351 def_kex = match_filter_whitelist(KEX_CLIENT_KEX, all_kex); 2352 def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key); 2353 def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig); 2354 #define ASSEMBLE(what, defaults, all) \ 2355 do { \ 2356 if ((r = kex_assemble_names(&options->what, \ 2357 defaults, all)) != 0) \ 2358 fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ 2359 } while (0) 2360 ASSEMBLE(ciphers, def_cipher, all_cipher); 2361 ASSEMBLE(macs, def_mac, all_mac); 2362 ASSEMBLE(kex_algorithms, def_kex, all_kex); 2363 ASSEMBLE(hostbased_key_types, def_key, all_key); 2364 ASSEMBLE(pubkey_key_types, def_key, all_key); 2365 ASSEMBLE(ca_sign_algorithms, def_sig, all_sig); 2366 #undef ASSEMBLE 2367 free(all_cipher); 2368 free(all_mac); 2369 free(all_kex); 2370 free(all_key); 2371 free(all_sig); 2372 free(def_cipher); 2373 free(def_mac); 2374 free(def_kex); 2375 kex_default_pk_alg_filtered = def_key; /* save for later use */ 2376 free(def_sig); 2377 2378 if (options->send_version_first == -1) 2379 options->send_version_first = 1; 2380 #define CLEAR_ON_NONE(v) \ 2381 do { \ 2382 if (option_clear_or_none(v)) { \ 2383 free(v); \ 2384 v = NULL; \ 2385 } \ 2386 } while(0) 2387 CLEAR_ON_NONE(options->local_command); 2388 CLEAR_ON_NONE(options->remote_command); 2389 CLEAR_ON_NONE(options->proxy_command); 2390 CLEAR_ON_NONE(options->control_path); 2391 CLEAR_ON_NONE(options->revoked_host_keys); 2392 CLEAR_ON_NONE(options->pkcs11_provider); 2393 CLEAR_ON_NONE(options->sk_provider); 2394 if (options->jump_host != NULL && 2395 strcmp(options->jump_host, "none") == 0 && 2396 options->jump_port == 0 && options->jump_user == NULL) { 2397 free(options->jump_host); 2398 options->jump_host = NULL; 2399 } 2400 /* options->identity_agent distinguishes NULL from 'none' */ 2401 /* options->user will be set in the main program if appropriate */ 2402 /* options->hostname will be set in the main program if appropriate */ 2403 /* options->host_key_alias should not be set by default */ 2404 /* options->preferred_authentications will be set in ssh */ 2405 } 2406 2407 struct fwdarg { 2408 char *arg; 2409 int ispath; 2410 }; 2411 2412 /* 2413 * parse_fwd_field 2414 * parses the next field in a port forwarding specification. 2415 * sets fwd to the parsed field and advances p past the colon 2416 * or sets it to NULL at end of string. 2417 * returns 0 on success, else non-zero. 2418 */ 2419 static int 2420 parse_fwd_field(char **p, struct fwdarg *fwd) 2421 { 2422 char *ep, *cp = *p; 2423 int ispath = 0; 2424 2425 if (*cp == '\0') { 2426 *p = NULL; 2427 return -1; /* end of string */ 2428 } 2429 2430 /* 2431 * A field escaped with square brackets is used literally. 2432 * XXX - allow ']' to be escaped via backslash? 2433 */ 2434 if (*cp == '[') { 2435 /* find matching ']' */ 2436 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) { 2437 if (*ep == '/') 2438 ispath = 1; 2439 } 2440 /* no matching ']' or not at end of field. */ 2441 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0')) 2442 return -1; 2443 /* NUL terminate the field and advance p past the colon */ 2444 *ep++ = '\0'; 2445 if (*ep != '\0') 2446 *ep++ = '\0'; 2447 fwd->arg = cp + 1; 2448 fwd->ispath = ispath; 2449 *p = ep; 2450 return 0; 2451 } 2452 2453 for (cp = *p; *cp != '\0'; cp++) { 2454 switch (*cp) { 2455 case '\\': 2456 memmove(cp, cp + 1, strlen(cp + 1) + 1); 2457 if (*cp == '\0') 2458 return -1; 2459 break; 2460 case '/': 2461 ispath = 1; 2462 break; 2463 case ':': 2464 *cp++ = '\0'; 2465 goto done; 2466 } 2467 } 2468 done: 2469 fwd->arg = *p; 2470 fwd->ispath = ispath; 2471 *p = cp; 2472 return 0; 2473 } 2474 2475 /* 2476 * parse_forward 2477 * parses a string containing a port forwarding specification of the form: 2478 * dynamicfwd == 0 2479 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath 2480 * listenpath:connectpath 2481 * dynamicfwd == 1 2482 * [listenhost:]listenport 2483 * returns number of arguments parsed or zero on error 2484 */ 2485 int 2486 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 2487 { 2488 struct fwdarg fwdargs[4]; 2489 char *p, *cp; 2490 int i; 2491 2492 memset(fwd, 0, sizeof(*fwd)); 2493 memset(fwdargs, 0, sizeof(fwdargs)); 2494 2495 cp = p = xstrdup(fwdspec); 2496 2497 /* skip leading spaces */ 2498 while (isspace((u_char)*cp)) 2499 cp++; 2500 2501 for (i = 0; i < 4; ++i) { 2502 if (parse_fwd_field(&cp, &fwdargs[i]) != 0) 2503 break; 2504 } 2505 2506 /* Check for trailing garbage */ 2507 if (cp != NULL && *cp != '\0') { 2508 i = 0; /* failure */ 2509 } 2510 2511 switch (i) { 2512 case 1: 2513 if (fwdargs[0].ispath) { 2514 fwd->listen_path = xstrdup(fwdargs[0].arg); 2515 fwd->listen_port = PORT_STREAMLOCAL; 2516 } else { 2517 fwd->listen_host = NULL; 2518 fwd->listen_port = a2port(fwdargs[0].arg); 2519 } 2520 fwd->connect_host = xstrdup("socks"); 2521 break; 2522 2523 case 2: 2524 if (fwdargs[0].ispath && fwdargs[1].ispath) { 2525 fwd->listen_path = xstrdup(fwdargs[0].arg); 2526 fwd->listen_port = PORT_STREAMLOCAL; 2527 fwd->connect_path = xstrdup(fwdargs[1].arg); 2528 fwd->connect_port = PORT_STREAMLOCAL; 2529 } else if (fwdargs[1].ispath) { 2530 fwd->listen_host = NULL; 2531 fwd->listen_port = a2port(fwdargs[0].arg); 2532 fwd->connect_path = xstrdup(fwdargs[1].arg); 2533 fwd->connect_port = PORT_STREAMLOCAL; 2534 } else { 2535 fwd->listen_host = xstrdup(fwdargs[0].arg); 2536 fwd->listen_port = a2port(fwdargs[1].arg); 2537 fwd->connect_host = xstrdup("socks"); 2538 } 2539 break; 2540 2541 case 3: 2542 if (fwdargs[0].ispath) { 2543 fwd->listen_path = xstrdup(fwdargs[0].arg); 2544 fwd->listen_port = PORT_STREAMLOCAL; 2545 fwd->connect_host = xstrdup(fwdargs[1].arg); 2546 fwd->connect_port = a2port(fwdargs[2].arg); 2547 } else if (fwdargs[2].ispath) { 2548 fwd->listen_host = xstrdup(fwdargs[0].arg); 2549 fwd->listen_port = a2port(fwdargs[1].arg); 2550 fwd->connect_path = xstrdup(fwdargs[2].arg); 2551 fwd->connect_port = PORT_STREAMLOCAL; 2552 } else { 2553 fwd->listen_host = NULL; 2554 fwd->listen_port = a2port(fwdargs[0].arg); 2555 fwd->connect_host = xstrdup(fwdargs[1].arg); 2556 fwd->connect_port = a2port(fwdargs[2].arg); 2557 } 2558 break; 2559 2560 case 4: 2561 fwd->listen_host = xstrdup(fwdargs[0].arg); 2562 fwd->listen_port = a2port(fwdargs[1].arg); 2563 fwd->connect_host = xstrdup(fwdargs[2].arg); 2564 fwd->connect_port = a2port(fwdargs[3].arg); 2565 break; 2566 default: 2567 i = 0; /* failure */ 2568 } 2569 2570 free(p); 2571 2572 if (dynamicfwd) { 2573 if (!(i == 1 || i == 2)) 2574 goto fail_free; 2575 } else { 2576 if (!(i == 3 || i == 4)) { 2577 if (fwd->connect_path == NULL && 2578 fwd->listen_path == NULL) 2579 goto fail_free; 2580 } 2581 if (fwd->connect_port <= 0 && fwd->connect_path == NULL) 2582 goto fail_free; 2583 } 2584 2585 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) || 2586 (!remotefwd && fwd->listen_port == 0)) 2587 goto fail_free; 2588 if (fwd->connect_host != NULL && 2589 strlen(fwd->connect_host) >= NI_MAXHOST) 2590 goto fail_free; 2591 /* XXX - if connecting to a remote socket, max sun len may not match this host */ 2592 if (fwd->connect_path != NULL && 2593 strlen(fwd->connect_path) >= PATH_MAX_SUN) 2594 goto fail_free; 2595 if (fwd->listen_host != NULL && 2596 strlen(fwd->listen_host) >= NI_MAXHOST) 2597 goto fail_free; 2598 if (fwd->listen_path != NULL && 2599 strlen(fwd->listen_path) >= PATH_MAX_SUN) 2600 goto fail_free; 2601 2602 return (i); 2603 2604 fail_free: 2605 free(fwd->connect_host); 2606 fwd->connect_host = NULL; 2607 free(fwd->connect_path); 2608 fwd->connect_path = NULL; 2609 free(fwd->listen_host); 2610 fwd->listen_host = NULL; 2611 free(fwd->listen_path); 2612 fwd->listen_path = NULL; 2613 return (0); 2614 } 2615 2616 int 2617 parse_jump(const char *s, Options *o, int active) 2618 { 2619 char *orig, *sdup, *cp; 2620 char *host = NULL, *user = NULL; 2621 int ret = -1, port = -1, first; 2622 2623 active &= o->proxy_command == NULL && o->jump_host == NULL; 2624 2625 orig = sdup = xstrdup(s); 2626 first = active; 2627 do { 2628 if (strcasecmp(s, "none") == 0) 2629 break; 2630 if ((cp = strrchr(sdup, ',')) == NULL) 2631 cp = sdup; /* last */ 2632 else 2633 *cp++ = '\0'; 2634 2635 if (first) { 2636 /* First argument and configuration is active */ 2637 if (parse_ssh_uri(cp, &user, &host, &port) == -1 || 2638 parse_user_host_port(cp, &user, &host, &port) != 0) 2639 goto out; 2640 } else { 2641 /* Subsequent argument or inactive configuration */ 2642 if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 || 2643 parse_user_host_port(cp, NULL, NULL, NULL) != 0) 2644 goto out; 2645 } 2646 first = 0; /* only check syntax for subsequent hosts */ 2647 } while (cp != sdup); 2648 /* success */ 2649 if (active) { 2650 if (strcasecmp(s, "none") == 0) { 2651 o->jump_host = xstrdup("none"); 2652 o->jump_port = 0; 2653 } else { 2654 o->jump_user = user; 2655 o->jump_host = host; 2656 o->jump_port = port; 2657 o->proxy_command = xstrdup("none"); 2658 user = host = NULL; 2659 if ((cp = strrchr(s, ',')) != NULL && cp != s) { 2660 o->jump_extra = xstrdup(s); 2661 o->jump_extra[cp - s] = '\0'; 2662 } 2663 } 2664 } 2665 ret = 0; 2666 out: 2667 free(orig); 2668 free(user); 2669 free(host); 2670 return ret; 2671 } 2672 2673 int 2674 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp) 2675 { 2676 const char *path; 2677 int r; 2678 2679 r = parse_uri("ssh", uri, userp, hostp, portp, &path); 2680 if (r == 0 && path != NULL) 2681 r = -1; /* path not allowed */ 2682 return r; 2683 } 2684 2685 /* XXX the following is a near-vebatim copy from servconf.c; refactor */ 2686 static const char * 2687 fmt_multistate_int(int val, const struct multistate *m) 2688 { 2689 u_int i; 2690 2691 for (i = 0; m[i].key != NULL; i++) { 2692 if (m[i].value == val) 2693 return m[i].key; 2694 } 2695 return "UNKNOWN"; 2696 } 2697 2698 static const char * 2699 fmt_intarg(OpCodes code, int val) 2700 { 2701 if (val == -1) 2702 return "unset"; 2703 switch (code) { 2704 case oAddressFamily: 2705 return fmt_multistate_int(val, multistate_addressfamily); 2706 case oVerifyHostKeyDNS: 2707 case oUpdateHostkeys: 2708 return fmt_multistate_int(val, multistate_yesnoask); 2709 case oStrictHostKeyChecking: 2710 return fmt_multistate_int(val, multistate_strict_hostkey); 2711 case oControlMaster: 2712 return fmt_multistate_int(val, multistate_controlmaster); 2713 case oTunnel: 2714 return fmt_multistate_int(val, multistate_tunnel); 2715 case oRequestTTY: 2716 return fmt_multistate_int(val, multistate_requesttty); 2717 case oCanonicalizeHostname: 2718 return fmt_multistate_int(val, multistate_canonicalizehostname); 2719 case oAddKeysToAgent: 2720 return fmt_multistate_int(val, multistate_yesnoaskconfirm); 2721 case oFingerprintHash: 2722 return ssh_digest_alg_name(val); 2723 default: 2724 switch (val) { 2725 case 0: 2726 return "no"; 2727 case 1: 2728 return "yes"; 2729 default: 2730 return "UNKNOWN"; 2731 } 2732 } 2733 } 2734 2735 static const char * 2736 lookup_opcode_name(OpCodes code) 2737 { 2738 u_int i; 2739 2740 for (i = 0; keywords[i].name != NULL; i++) 2741 if (keywords[i].opcode == code) 2742 return(keywords[i].name); 2743 return "UNKNOWN"; 2744 } 2745 2746 static void 2747 dump_cfg_int(OpCodes code, int val) 2748 { 2749 printf("%s %d\n", lookup_opcode_name(code), val); 2750 } 2751 2752 static void 2753 dump_cfg_fmtint(OpCodes code, int val) 2754 { 2755 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); 2756 } 2757 2758 static void 2759 dump_cfg_string(OpCodes code, const char *val) 2760 { 2761 if (val == NULL) 2762 return; 2763 printf("%s %s\n", lookup_opcode_name(code), val); 2764 } 2765 2766 static void 2767 dump_cfg_strarray(OpCodes code, u_int count, char **vals) 2768 { 2769 u_int i; 2770 2771 for (i = 0; i < count; i++) 2772 printf("%s %s\n", lookup_opcode_name(code), vals[i]); 2773 } 2774 2775 static void 2776 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) 2777 { 2778 u_int i; 2779 2780 printf("%s", lookup_opcode_name(code)); 2781 for (i = 0; i < count; i++) 2782 printf(" %s", vals[i]); 2783 printf("\n"); 2784 } 2785 2786 static void 2787 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds) 2788 { 2789 const struct Forward *fwd; 2790 u_int i; 2791 2792 /* oDynamicForward */ 2793 for (i = 0; i < count; i++) { 2794 fwd = &fwds[i]; 2795 if (code == oDynamicForward && fwd->connect_host != NULL && 2796 strcmp(fwd->connect_host, "socks") != 0) 2797 continue; 2798 if (code == oLocalForward && fwd->connect_host != NULL && 2799 strcmp(fwd->connect_host, "socks") == 0) 2800 continue; 2801 printf("%s", lookup_opcode_name(code)); 2802 if (fwd->listen_port == PORT_STREAMLOCAL) 2803 printf(" %s", fwd->listen_path); 2804 else if (fwd->listen_host == NULL) 2805 printf(" %d", fwd->listen_port); 2806 else { 2807 printf(" [%s]:%d", 2808 fwd->listen_host, fwd->listen_port); 2809 } 2810 if (code != oDynamicForward) { 2811 if (fwd->connect_port == PORT_STREAMLOCAL) 2812 printf(" %s", fwd->connect_path); 2813 else if (fwd->connect_host == NULL) 2814 printf(" %d", fwd->connect_port); 2815 else { 2816 printf(" [%s]:%d", 2817 fwd->connect_host, fwd->connect_port); 2818 } 2819 } 2820 printf("\n"); 2821 } 2822 } 2823 2824 void 2825 dump_client_config(Options *o, const char *host) 2826 { 2827 int i, r; 2828 char buf[8], *all_key; 2829 2830 /* 2831 * Expand HostKeyAlgorithms name lists. This isn't handled in 2832 * fill_default_options() like the other algorithm lists because 2833 * the host key algorithms are by default dynamically chosen based 2834 * on the host's keys found in known_hosts. 2835 */ 2836 all_key = sshkey_alg_list(0, 0, 1, ','); 2837 if ((r = kex_assemble_names(&o->hostkeyalgorithms, kex_default_pk_alg(), 2838 all_key)) != 0) 2839 fatal("%s: expand HostKeyAlgorithms: %s", __func__, ssh_err(r)); 2840 free(all_key); 2841 2842 /* Most interesting options first: user, host, port */ 2843 dump_cfg_string(oUser, o->user); 2844 dump_cfg_string(oHostname, host); 2845 dump_cfg_int(oPort, o->port); 2846 2847 /* Flag options */ 2848 dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent); 2849 dump_cfg_fmtint(oAddressFamily, o->address_family); 2850 dump_cfg_fmtint(oBatchMode, o->batch_mode); 2851 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); 2852 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname); 2853 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication); 2854 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip); 2855 dump_cfg_fmtint(oCompression, o->compression); 2856 dump_cfg_fmtint(oControlMaster, o->control_master); 2857 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); 2858 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); 2859 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); 2860 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); 2861 dump_cfg_fmtint(oForwardX11, o->forward_x11); 2862 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); 2863 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); 2864 #ifdef GSSAPI 2865 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); 2866 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); 2867 #endif /* GSSAPI */ 2868 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); 2869 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); 2870 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only); 2871 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication); 2872 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); 2873 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication); 2874 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command); 2875 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass); 2876 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication); 2877 dump_cfg_fmtint(oRequestTTY, o->request_tty); 2878 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 2879 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); 2880 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); 2881 dump_cfg_fmtint(oTunnel, o->tun_open); 2882 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); 2883 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); 2884 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); 2885 2886 /* Integer options */ 2887 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); 2888 dump_cfg_int(oConnectionAttempts, o->connection_attempts); 2889 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); 2890 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); 2891 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); 2892 dump_cfg_int(oServerAliveInterval, o->server_alive_interval); 2893 2894 /* String options */ 2895 dump_cfg_string(oBindAddress, o->bind_address); 2896 dump_cfg_string(oBindInterface, o->bind_interface); 2897 dump_cfg_string(oCiphers, o->ciphers); 2898 dump_cfg_string(oControlPath, o->control_path); 2899 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); 2900 dump_cfg_string(oHostKeyAlias, o->host_key_alias); 2901 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); 2902 dump_cfg_string(oIdentityAgent, o->identity_agent); 2903 dump_cfg_string(oIgnoreUnknown, o->ignored_unknown); 2904 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); 2905 dump_cfg_string(oKexAlgorithms, o->kex_algorithms); 2906 dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms); 2907 dump_cfg_string(oLocalCommand, o->local_command); 2908 dump_cfg_string(oRemoteCommand, o->remote_command); 2909 dump_cfg_string(oLogLevel, log_level_name(o->log_level)); 2910 dump_cfg_string(oMacs, o->macs); 2911 #ifdef ENABLE_PKCS11 2912 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); 2913 #endif 2914 dump_cfg_string(oSecurityKeyProvider, o->sk_provider); 2915 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); 2916 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types); 2917 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); 2918 dump_cfg_string(oXAuthLocation, o->xauth_location); 2919 2920 /* Forwards */ 2921 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); 2922 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); 2923 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); 2924 2925 /* String array options */ 2926 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); 2927 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); 2928 dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files); 2929 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); 2930 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); 2931 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); 2932 dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv); 2933 2934 /* Special cases */ 2935 2936 /* oForwardAgent */ 2937 if (o->forward_agent_sock_path == NULL) 2938 dump_cfg_fmtint(oForwardAgent, o->forward_agent); 2939 else 2940 dump_cfg_string(oForwardAgent, o->forward_agent_sock_path); 2941 2942 /* oConnectTimeout */ 2943 if (o->connection_timeout == -1) 2944 printf("connecttimeout none\n"); 2945 else 2946 dump_cfg_int(oConnectTimeout, o->connection_timeout); 2947 2948 /* oTunnelDevice */ 2949 printf("tunneldevice"); 2950 if (o->tun_local == SSH_TUNID_ANY) 2951 printf(" any"); 2952 else 2953 printf(" %d", o->tun_local); 2954 if (o->tun_remote == SSH_TUNID_ANY) 2955 printf(":any"); 2956 else 2957 printf(":%d", o->tun_remote); 2958 printf("\n"); 2959 2960 /* oCanonicalizePermittedCNAMEs */ 2961 if ( o->num_permitted_cnames > 0) { 2962 printf("canonicalizePermittedcnames"); 2963 for (i = 0; i < o->num_permitted_cnames; i++) { 2964 printf(" %s:%s", o->permitted_cnames[i].source_list, 2965 o->permitted_cnames[i].target_list); 2966 } 2967 printf("\n"); 2968 } 2969 2970 /* oControlPersist */ 2971 if (o->control_persist == 0 || o->control_persist_timeout == 0) 2972 dump_cfg_fmtint(oControlPersist, o->control_persist); 2973 else 2974 dump_cfg_int(oControlPersist, o->control_persist_timeout); 2975 2976 /* oEscapeChar */ 2977 if (o->escape_char == SSH_ESCAPECHAR_NONE) 2978 printf("escapechar none\n"); 2979 else { 2980 vis(buf, o->escape_char, VIS_WHITE, 0); 2981 printf("escapechar %s\n", buf); 2982 } 2983 2984 /* oIPQoS */ 2985 printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); 2986 printf("%s\n", iptos2str(o->ip_qos_bulk)); 2987 2988 /* oRekeyLimit */ 2989 printf("rekeylimit %llu %d\n", 2990 (unsigned long long)o->rekey_limit, o->rekey_interval); 2991 2992 /* oStreamLocalBindMask */ 2993 printf("streamlocalbindmask 0%o\n", 2994 o->fwd_opts.streamlocal_bind_mask); 2995 2996 /* oLogFacility */ 2997 printf("syslogfacility %s\n", log_facility_name(o->log_facility)); 2998 2999 /* oProxyCommand / oProxyJump */ 3000 if (o->jump_host == NULL) 3001 dump_cfg_string(oProxyCommand, o->proxy_command); 3002 else { 3003 /* Check for numeric addresses */ 3004 i = strchr(o->jump_host, ':') != NULL || 3005 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host); 3006 snprintf(buf, sizeof(buf), "%d", o->jump_port); 3007 printf("proxyjump %s%s%s%s%s%s%s%s%s\n", 3008 /* optional additional jump spec */ 3009 o->jump_extra == NULL ? "" : o->jump_extra, 3010 o->jump_extra == NULL ? "" : ",", 3011 /* optional user */ 3012 o->jump_user == NULL ? "" : o->jump_user, 3013 o->jump_user == NULL ? "" : "@", 3014 /* opening [ if hostname is numeric */ 3015 i ? "[" : "", 3016 /* mandatory hostname */ 3017 o->jump_host, 3018 /* closing ] if hostname is numeric */ 3019 i ? "]" : "", 3020 /* optional port number */ 3021 o->jump_port <= 0 ? "" : ":", 3022 o->jump_port <= 0 ? "" : buf); 3023 } 3024 } 3025