LCOV - code coverage report
Current view: top level - openssh-6.6p1 - readconf.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 470 862 54.5 %
Date: 2014-08-01 Functions: 11 16 68.8 %
Branches: 287 736 39.0 %

           Branch data     Line data    Source code
       1                 :            : /* $OpenBSD: readconf.c,v 1.218 2014/02/23 20:11:36 djm Exp $ */
       2                 :            : /*
       3                 :            :  * Author: Tatu Ylonen <ylo@cs.hut.fi>
       4                 :            :  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
       5                 :            :  *                    All rights reserved
       6                 :            :  * Functions for reading the configuration files.
       7                 :            :  *
       8                 :            :  * As far as I am concerned, the code I have written for this software
       9                 :            :  * can be used freely for any purpose.  Any derived versions of this
      10                 :            :  * software must be clearly marked as such, and if the derived work is
      11                 :            :  * incompatible with the protocol description in the RFC file, it must be
      12                 :            :  * called by a name other than "ssh" or "Secure Shell".
      13                 :            :  */
      14                 :            : 
      15                 :            : #include "includes.h"
      16                 :            : 
      17                 :            : #include <sys/types.h>
      18                 :            : #include <sys/stat.h>
      19                 :            : #include <sys/socket.h>
      20                 :            : #include <sys/wait.h>
      21                 :            : 
      22                 :            : #include <netinet/in.h>
      23                 :            : #include <netinet/in_systm.h>
      24                 :            : #include <netinet/ip.h>
      25                 :            : #include <arpa/inet.h>
      26                 :            : 
      27                 :            : #include <ctype.h>
      28                 :            : #include <errno.h>
      29                 :            : #include <fcntl.h>
      30                 :            : #include <netdb.h>
      31                 :            : #ifdef HAVE_PATHS_H
      32                 :            : # include <paths.h>
      33                 :            : #endif
      34                 :            : #include <pwd.h>
      35                 :            : #include <signal.h>
      36                 :            : #include <stdarg.h>
      37                 :            : #include <stdio.h>
      38                 :            : #include <string.h>
      39                 :            : #include <unistd.h>
      40                 :            : #ifdef HAVE_UTIL_H
      41                 :            : #include <util.h>
      42                 :            : #endif
      43                 :            : 
      44                 :            : #include "xmalloc.h"
      45                 :            : #include "ssh.h"
      46                 :            : #include "compat.h"
      47                 :            : #include "cipher.h"
      48                 :            : #include "pathnames.h"
      49                 :            : #include "log.h"
      50                 :            : #include "key.h"
      51                 :            : #include "readconf.h"
      52                 :            : #include "match.h"
      53                 :            : #include "misc.h"
      54                 :            : #include "buffer.h"
      55                 :            : #include "kex.h"
      56                 :            : #include "mac.h"
      57                 :            : #include "uidswap.h"
      58                 :            : 
      59                 :            : /* Format of the configuration file:
      60                 :            : 
      61                 :            :    # Configuration data is parsed as follows:
      62                 :            :    #  1. command line options
      63                 :            :    #  2. user-specific file
      64                 :            :    #  3. system-wide file
      65                 :            :    # Any configuration value is only changed the first time it is set.
      66                 :            :    # Thus, host-specific definitions should be at the beginning of the
      67                 :            :    # configuration file, and defaults at the end.
      68                 :            : 
      69                 :            :    # Host-specific declarations.  These may override anything above.  A single
      70                 :            :    # host may match multiple declarations; these are processed in the order
      71                 :            :    # that they are given in.
      72                 :            : 
      73                 :            :    Host *.ngs.fi ngs.fi
      74                 :            :      User foo
      75                 :            : 
      76                 :            :    Host fake.com
      77                 :            :      HostName another.host.name.real.org
      78                 :            :      User blaah
      79                 :            :      Port 34289
      80                 :            :      ForwardX11 no
      81                 :            :      ForwardAgent no
      82                 :            : 
      83                 :            :    Host books.com
      84                 :            :      RemoteForward 9999 shadows.cs.hut.fi:9999
      85                 :            :      Cipher 3des
      86                 :            : 
      87                 :            :    Host fascist.blob.com
      88                 :            :      Port 23123
      89                 :            :      User tylonen
      90                 :            :      PasswordAuthentication no
      91                 :            : 
      92                 :            :    Host puukko.hut.fi
      93                 :            :      User t35124p
      94                 :            :      ProxyCommand ssh-proxy %h %p
      95                 :            : 
      96                 :            :    Host *.fr
      97                 :            :      PublicKeyAuthentication no
      98                 :            : 
      99                 :            :    Host *.su
     100                 :            :      Cipher none
     101                 :            :      PasswordAuthentication no
     102                 :            : 
     103                 :            :    Host vpn.fake.com
     104                 :            :      Tunnel yes
     105                 :            :      TunnelDevice 3
     106                 :            : 
     107                 :            :    # Defaults for various options
     108                 :            :    Host *
     109                 :            :      ForwardAgent no
     110                 :            :      ForwardX11 no
     111                 :            :      PasswordAuthentication yes
     112                 :            :      RSAAuthentication yes
     113                 :            :      RhostsRSAAuthentication yes
     114                 :            :      StrictHostKeyChecking yes
     115                 :            :      TcpKeepAlive no
     116                 :            :      IdentityFile ~/.ssh/identity
     117                 :            :      Port 22
     118                 :            :      EscapeChar ~
     119                 :            : 
     120                 :            : */
     121                 :            : 
     122                 :            : /* Keyword tokens. */
     123                 :            : 
     124                 :            : typedef enum {
     125                 :            :         oBadOption,
     126                 :            :         oHost, oMatch,
     127                 :            :         oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
     128                 :            :         oGatewayPorts, oExitOnForwardFailure,
     129                 :            :         oPasswordAuthentication, oRSAAuthentication,
     130                 :            :         oChallengeResponseAuthentication, oXAuthLocation,
     131                 :            :         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
     132                 :            :         oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
     133                 :            :         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
     134                 :            :         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
     135                 :            :         oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
     136                 :            :         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
     137                 :            :         oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
     138                 :            :         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
     139                 :            :         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
     140                 :            :         oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
     141                 :            :         oClearAllForwardings, oNoHostAuthenticationForLocalhost,
     142                 :            :         oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
     143                 :            :         oAddressFamily, oGssAuthentication, oGssDelegateCreds,
     144                 :            :         oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
     145                 :            :         oSendEnv, oControlPath, oControlMaster, oControlPersist,
     146                 :            :         oHashKnownHosts,
     147                 :            :         oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
     148                 :            :         oVisualHostKey, oUseRoaming,
     149                 :            :         oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
     150                 :            :         oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
     151                 :            :         oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
     152                 :            :         oIgnoredUnknownOption, oDeprecated, oUnsupported
     153                 :            : } OpCodes;
     154                 :            : 
     155                 :            : /* Textual representations of the tokens. */
     156                 :            : 
     157                 :            : static struct {
     158                 :            :         const char *name;
     159                 :            :         OpCodes opcode;
     160                 :            : } keywords[] = {
     161                 :            :         { "forwardagent", oForwardAgent },
     162                 :            :         { "forwardx11", oForwardX11 },
     163                 :            :         { "forwardx11trusted", oForwardX11Trusted },
     164                 :            :         { "forwardx11timeout", oForwardX11Timeout },
     165                 :            :         { "exitonforwardfailure", oExitOnForwardFailure },
     166                 :            :         { "xauthlocation", oXAuthLocation },
     167                 :            :         { "gatewayports", oGatewayPorts },
     168                 :            :         { "useprivilegedport", oUsePrivilegedPort },
     169                 :            :         { "rhostsauthentication", oDeprecated },
     170                 :            :         { "passwordauthentication", oPasswordAuthentication },
     171                 :            :         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
     172                 :            :         { "kbdinteractivedevices", oKbdInteractiveDevices },
     173                 :            :         { "rsaauthentication", oRSAAuthentication },
     174                 :            :         { "pubkeyauthentication", oPubkeyAuthentication },
     175                 :            :         { "dsaauthentication", oPubkeyAuthentication },                   /* alias */
     176                 :            :         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
     177                 :            :         { "hostbasedauthentication", oHostbasedAuthentication },
     178                 :            :         { "challengeresponseauthentication", oChallengeResponseAuthentication },
     179                 :            :         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
     180                 :            :         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
     181                 :            :         { "kerberosauthentication", oUnsupported },
     182                 :            :         { "kerberostgtpassing", oUnsupported },
     183                 :            :         { "afstokenpassing", oUnsupported },
     184                 :            : #if defined(GSSAPI)
     185                 :            :         { "gssapiauthentication", oGssAuthentication },
     186                 :            :         { "gssapidelegatecredentials", oGssDelegateCreds },
     187                 :            : #else
     188                 :            :         { "gssapiauthentication", oUnsupported },
     189                 :            :         { "gssapidelegatecredentials", oUnsupported },
     190                 :            : #endif
     191                 :            :         { "fallbacktorsh", oDeprecated },
     192                 :            :         { "usersh", oDeprecated },
     193                 :            :         { "identityfile", oIdentityFile },
     194                 :            :         { "identityfile2", oIdentityFile },                   /* obsolete */
     195                 :            :         { "identitiesonly", oIdentitiesOnly },
     196                 :            :         { "hostname", oHostName },
     197                 :            :         { "hostkeyalias", oHostKeyAlias },
     198                 :            :         { "proxycommand", oProxyCommand },
     199                 :            :         { "port", oPort },
     200                 :            :         { "cipher", oCipher },
     201                 :            :         { "ciphers", oCiphers },
     202                 :            :         { "macs", oMacs },
     203                 :            :         { "protocol", oProtocol },
     204                 :            :         { "remoteforward", oRemoteForward },
     205                 :            :         { "localforward", oLocalForward },
     206                 :            :         { "user", oUser },
     207                 :            :         { "host", oHost },
     208                 :            :         { "match", oMatch },
     209                 :            :         { "escapechar", oEscapeChar },
     210                 :            :         { "globalknownhostsfile", oGlobalKnownHostsFile },
     211                 :            :         { "globalknownhostsfile2", oDeprecated },
     212                 :            :         { "userknownhostsfile", oUserKnownHostsFile },
     213                 :            :         { "userknownhostsfile2", oDeprecated }, 
     214                 :            :         { "connectionattempts", oConnectionAttempts },
     215                 :            :         { "batchmode", oBatchMode },
     216                 :            :         { "checkhostip", oCheckHostIP },
     217                 :            :         { "stricthostkeychecking", oStrictHostKeyChecking },
     218                 :            :         { "compression", oCompression },
     219                 :            :         { "compressionlevel", oCompressionLevel },
     220                 :            :         { "tcpkeepalive", oTCPKeepAlive },
     221                 :            :         { "keepalive", oTCPKeepAlive },                               /* obsolete */
     222                 :            :         { "numberofpasswordprompts", oNumberOfPasswordPrompts },
     223                 :            :         { "loglevel", oLogLevel },
     224                 :            :         { "dynamicforward", oDynamicForward },
     225                 :            :         { "preferredauthentications", oPreferredAuthentications },
     226                 :            :         { "hostkeyalgorithms", oHostKeyAlgorithms },
     227                 :            :         { "bindaddress", oBindAddress },
     228                 :            : #ifdef ENABLE_PKCS11
     229                 :            :         { "smartcarddevice", oPKCS11Provider },
     230                 :            :         { "pkcs11provider", oPKCS11Provider },
     231                 :            : #else
     232                 :            :         { "smartcarddevice", oUnsupported },
     233                 :            :         { "pkcs11provider", oUnsupported },
     234                 :            : #endif
     235                 :            :         { "clearallforwardings", oClearAllForwardings },
     236                 :            :         { "enablesshkeysign", oEnableSSHKeysign },
     237                 :            :         { "verifyhostkeydns", oVerifyHostKeyDNS },
     238                 :            :         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
     239                 :            :         { "rekeylimit", oRekeyLimit },
     240                 :            :         { "connecttimeout", oConnectTimeout },
     241                 :            :         { "addressfamily", oAddressFamily },
     242                 :            :         { "serveraliveinterval", oServerAliveInterval },
     243                 :            :         { "serveralivecountmax", oServerAliveCountMax },
     244                 :            :         { "sendenv", oSendEnv },
     245                 :            :         { "controlpath", oControlPath },
     246                 :            :         { "controlmaster", oControlMaster },
     247                 :            :         { "controlpersist", oControlPersist },
     248                 :            :         { "hashknownhosts", oHashKnownHosts },
     249                 :            :         { "tunnel", oTunnel },
     250                 :            :         { "tunneldevice", oTunnelDevice },
     251                 :            :         { "localcommand", oLocalCommand },
     252                 :            :         { "permitlocalcommand", oPermitLocalCommand },
     253                 :            :         { "visualhostkey", oVisualHostKey },
     254                 :            :         { "useroaming", oUseRoaming },
     255                 :            :         { "kexalgorithms", oKexAlgorithms },
     256                 :            :         { "ipqos", oIPQoS },
     257                 :            :         { "requesttty", oRequestTTY },
     258                 :            :         { "proxyusefdpass", oProxyUseFdpass },
     259                 :            :         { "canonicaldomains", oCanonicalDomains },
     260                 :            :         { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
     261                 :            :         { "canonicalizehostname", oCanonicalizeHostname },
     262                 :            :         { "canonicalizemaxdots", oCanonicalizeMaxDots },
     263                 :            :         { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
     264                 :            :         { "ignoreunknown", oIgnoreUnknown },
     265                 :            : 
     266                 :            :         { NULL, oBadOption }
     267                 :            : };
     268                 :            : 
     269                 :            : /*
     270                 :            :  * Adds a local TCP/IP port forward to options.  Never returns if there is an
     271                 :            :  * error.
     272                 :            :  */
     273                 :            : 
     274                 :            : void
     275                 :         84 : add_local_forward(Options *options, const Forward *newfwd)
     276                 :            : {
     277                 :            :         Forward *fwd;
     278                 :            : #ifndef NO_IPPORT_RESERVED_CONCEPT
     279                 :            :         extern uid_t original_real_uid;
     280 [ -  + ][ #  # ]:         84 :         if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
     281                 :          0 :                 fatal("Privileged ports can only be forwarded by root.");
     282                 :            : #endif
     283                 :         84 :         options->local_forwards = xrealloc(options->local_forwards,
     284                 :         84 :             options->num_local_forwards + 1,
     285                 :            :             sizeof(*options->local_forwards));
     286                 :         84 :         fwd = &options->local_forwards[options->num_local_forwards++];
     287                 :            : 
     288                 :         84 :         fwd->listen_host = newfwd->listen_host;
     289                 :         84 :         fwd->listen_port = newfwd->listen_port;
     290                 :         84 :         fwd->connect_host = newfwd->connect_host;
     291                 :         84 :         fwd->connect_port = newfwd->connect_port;
     292                 :         84 : }
     293                 :            : 
     294                 :            : /*
     295                 :            :  * Adds a remote TCP/IP port forward to options.  Never returns if there is
     296                 :            :  * an error.
     297                 :            :  */
     298                 :            : 
     299                 :            : void
     300                 :         73 : add_remote_forward(Options *options, const Forward *newfwd)
     301                 :            : {
     302                 :            :         Forward *fwd;
     303                 :            : 
     304                 :         73 :         options->remote_forwards = xrealloc(options->remote_forwards,
     305                 :         73 :             options->num_remote_forwards + 1,
     306                 :            :             sizeof(*options->remote_forwards));
     307                 :         73 :         fwd = &options->remote_forwards[options->num_remote_forwards++];
     308                 :            : 
     309                 :         73 :         fwd->listen_host = newfwd->listen_host;
     310                 :         73 :         fwd->listen_port = newfwd->listen_port;
     311                 :         73 :         fwd->connect_host = newfwd->connect_host;
     312                 :         73 :         fwd->connect_port = newfwd->connect_port;
     313                 :         73 :         fwd->handle = newfwd->handle;
     314                 :         73 :         fwd->allocated_port = 0;
     315                 :         73 : }
     316                 :            : 
     317                 :            : static void
     318                 :          8 : clear_forwardings(Options *options)
     319                 :            : {
     320                 :            :         int i;
     321                 :            : 
     322         [ +  + ]:         10 :         for (i = 0; i < options->num_local_forwards; i++) {
     323                 :          2 :                 free(options->local_forwards[i].listen_host);
     324                 :          2 :                 free(options->local_forwards[i].connect_host);
     325                 :            :         }
     326         [ +  + ]:          8 :         if (options->num_local_forwards > 0) {
     327                 :          2 :                 free(options->local_forwards);
     328                 :          2 :                 options->local_forwards = NULL;
     329                 :            :         }
     330                 :          8 :         options->num_local_forwards = 0;
     331         [ +  + ]:         10 :         for (i = 0; i < options->num_remote_forwards; i++) {
     332                 :          2 :                 free(options->remote_forwards[i].listen_host);
     333                 :          2 :                 free(options->remote_forwards[i].connect_host);
     334                 :            :         }
     335         [ +  + ]:          8 :         if (options->num_remote_forwards > 0) {
     336                 :          2 :                 free(options->remote_forwards);
     337                 :          2 :                 options->remote_forwards = NULL;
     338                 :            :         }
     339                 :          8 :         options->num_remote_forwards = 0;
     340                 :          8 :         options->tun_open = SSH_TUNMODE_NO;
     341                 :          8 : }
     342                 :            : 
     343                 :            : void
     344                 :       5532 : add_identity_file(Options *options, const char *dir, const char *filename,
     345                 :            :     int userprovided)
     346                 :            : {
     347                 :            :         char *path;
     348                 :            : 
     349         [ -  + ]:       5532 :         if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
     350                 :          0 :                 fatal("Too many identity files specified (max %d)",
     351                 :            :                     SSH_MAX_IDENTITY_FILES);
     352                 :            : 
     353         [ +  - ]:       5532 :         if (dir == NULL) /* no dir, filename is absolute */
     354                 :       5532 :                 path = xstrdup(filename);
     355                 :            :         else
     356                 :          0 :                 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
     357                 :            : 
     358                 :       5532 :         options->identity_file_userprovided[options->num_identity_files] =
     359                 :            :             userprovided;
     360                 :       5532 :         options->identity_files[options->num_identity_files++] = path;
     361                 :       5532 : }
     362                 :            : 
     363                 :            : int
     364                 :          0 : default_ssh_port(void)
     365                 :            : {
     366                 :            :         static int port;
     367                 :            :         struct servent *sp;
     368                 :            : 
     369         [ #  # ]:          0 :         if (port == 0) {
     370                 :          0 :                 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
     371 [ #  # ][ #  # ]:          0 :                 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
     372                 :            :         }
     373                 :          0 :         return port;
     374                 :            : }
     375                 :            : 
     376                 :            : /*
     377                 :            :  * Execute a command in a shell.
     378                 :            :  * Return its exit status or -1 on abnormal exit.
     379                 :            :  */
     380                 :            : static int
     381                 :          0 : execute_in_shell(const char *cmd)
     382                 :            : {
     383                 :            :         char *shell, *command_string;
     384                 :            :         pid_t pid;
     385                 :            :         int devnull, status;
     386                 :            :         extern uid_t original_real_uid;
     387                 :            : 
     388         [ #  # ]:          0 :         if ((shell = getenv("SHELL")) == NULL)
     389                 :          0 :                 shell = _PATH_BSHELL;
     390                 :            : 
     391                 :            :         /*
     392                 :            :          * Use "exec" to avoid "sh -c" processes on some platforms
     393                 :            :          * (e.g. Solaris)
     394                 :            :          */
     395                 :          0 :         xasprintf(&command_string, "exec %s", cmd);
     396                 :            : 
     397                 :            :         /* Need this to redirect subprocess stdin/out */
     398         [ #  # ]:          0 :         if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
     399                 :          0 :                 fatal("open(/dev/null): %s", strerror(errno));
     400                 :            : 
     401                 :          0 :         debug("Executing command: '%.500s'", cmd);
     402                 :            : 
     403                 :            :         /* Fork and execute the command. */
     404         [ #  # ]:          0 :         if ((pid = fork()) == 0) {
     405                 :            :                 char *argv[4];
     406                 :            : 
     407                 :            :                 /* Child.  Permanently give up superuser privileges. */
     408                 :          0 :                 permanently_drop_suid(original_real_uid);
     409                 :            : 
     410                 :            :                 /* Redirect child stdin and stdout. Leave stderr */
     411         [ #  # ]:          0 :                 if (dup2(devnull, STDIN_FILENO) == -1)
     412                 :          0 :                         fatal("dup2: %s", strerror(errno));
     413         [ #  # ]:          0 :                 if (dup2(devnull, STDOUT_FILENO) == -1)
     414                 :          0 :                         fatal("dup2: %s", strerror(errno));
     415         [ #  # ]:          0 :                 if (devnull > STDERR_FILENO)
     416                 :          0 :                         close(devnull);
     417                 :          0 :                 closefrom(STDERR_FILENO + 1);
     418                 :            : 
     419                 :          0 :                 argv[0] = shell;
     420                 :          0 :                 argv[1] = "-c";
     421                 :          0 :                 argv[2] = command_string;
     422                 :          0 :                 argv[3] = NULL;
     423                 :            : 
     424                 :          0 :                 execv(argv[0], argv);
     425                 :          0 :                 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
     426                 :            :                 /* Die with signal to make this error apparent to parent. */
     427                 :          0 :                 signal(SIGTERM, SIG_DFL);
     428                 :          0 :                 kill(getpid(), SIGTERM);
     429                 :          0 :                 _exit(1);
     430                 :            :         }
     431                 :            :         /* Parent. */
     432         [ #  # ]:          0 :         if (pid < 0)
     433                 :          0 :                 fatal("%s: fork: %.100s", __func__, strerror(errno));
     434                 :            : 
     435                 :          0 :         close(devnull);
     436                 :          0 :         free(command_string);
     437                 :            : 
     438         [ #  # ]:          0 :         while (waitpid(pid, &status, 0) == -1) {
     439         [ #  # ]:          0 :                 if (errno != EINTR && errno != EAGAIN)
     440                 :          0 :                         fatal("%s: waitpid: %s", __func__, strerror(errno));
     441                 :            :         }
     442         [ #  # ]:          0 :         if (!WIFEXITED(status)) {
     443                 :          0 :                 error("command '%.100s' exited abnormally", cmd);
     444                 :          0 :                 return -1;
     445                 :            :         } 
     446                 :          0 :         debug3("command returned status %d", WEXITSTATUS(status));
     447                 :          0 :         return WEXITSTATUS(status);
     448                 :            : }
     449                 :            : 
     450                 :            : /*
     451                 :            :  * Parse and execute a Match directive.
     452                 :            :  */
     453                 :            : static int
     454                 :          0 : match_cfg_line(Options *options, char **condition, struct passwd *pw,
     455                 :            :     const char *host_arg, const char *filename, int linenum)
     456                 :            : {
     457                 :          0 :         char *arg, *attrib, *cmd, *cp = *condition, *host;
     458                 :            :         const char *ruser;
     459                 :          0 :         int r, port, result = 1, attributes = 0;
     460                 :            :         size_t len;
     461                 :            :         char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
     462                 :            : 
     463                 :            :         /*
     464                 :            :          * Configuration is likely to be incomplete at this point so we
     465                 :            :          * must be prepared to use default values.
     466                 :            :          */
     467         [ #  # ]:          0 :         port = options->port <= 0 ? default_ssh_port() : options->port;
     468         [ #  # ]:          0 :         ruser = options->user == NULL ? pw->pw_name : options->user;
     469         [ #  # ]:          0 :         if (options->hostname != NULL) {
     470                 :            :                 /* NB. Please keep in sync with ssh.c:main() */
     471                 :          0 :                 host = percent_expand(options->hostname,
     472                 :            :                     "h", host_arg, (char *)NULL);
     473                 :            :         } else
     474                 :          0 :                 host = xstrdup(host_arg);
     475                 :            : 
     476                 :          0 :         debug3("checking match for '%s' host %s", cp, host);
     477 [ #  # ][ #  # ]:          0 :         while ((attrib = strdelim(&cp)) && *attrib != '\0') {
     478                 :          0 :                 attributes++;
     479         [ #  # ]:          0 :                 if (strcasecmp(attrib, "all") == 0) {
     480 [ #  # ][ #  # ]:          0 :                         if (attributes != 1 ||
     481         [ #  # ]:          0 :                             ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
     482                 :          0 :                                 error("'all' cannot be combined with other "
     483                 :            :                                     "Match attributes");
     484                 :          0 :                                 result = -1;
     485                 :            :                                 goto out;
     486                 :            :                         }
     487                 :          0 :                         *condition = cp;
     488                 :          0 :                         result = 1;
     489                 :            :                         goto out;
     490                 :            :                 }
     491 [ #  # ][ #  # ]:          0 :                 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
     492                 :          0 :                         error("Missing Match criteria for %s", attrib);
     493                 :          0 :                         result = -1;
     494                 :            :                         goto out;
     495                 :            :                 }
     496                 :          0 :                 len = strlen(arg);
     497         [ #  # ]:          0 :                 if (strcasecmp(attrib, "host") == 0) {
     498         [ #  # ]:          0 :                         if (match_hostname(host, arg, len) != 1)
     499                 :            :                                 result = 0;
     500                 :            :                         else
     501                 :          0 :                                 debug("%.200s line %d: matched 'Host %.100s' ",
     502                 :            :                                     filename, linenum, host);
     503         [ #  # ]:          0 :                 } else if (strcasecmp(attrib, "originalhost") == 0) {
     504         [ #  # ]:          0 :                         if (match_hostname(host_arg, arg, len) != 1)
     505                 :            :                                 result = 0;
     506                 :            :                         else
     507                 :          0 :                                 debug("%.200s line %d: matched "
     508                 :            :                                     "'OriginalHost %.100s' ",
     509                 :            :                                     filename, linenum, host_arg);
     510         [ #  # ]:          0 :                 } else if (strcasecmp(attrib, "user") == 0) {
     511         [ #  # ]:          0 :                         if (match_pattern_list(ruser, arg, len, 0) != 1)
     512                 :            :                                 result = 0;
     513                 :            :                         else
     514                 :          0 :                                 debug("%.200s line %d: matched 'User %.100s' ",
     515                 :            :                                     filename, linenum, ruser);
     516         [ #  # ]:          0 :                 } else if (strcasecmp(attrib, "localuser") == 0) {
     517         [ #  # ]:          0 :                         if (match_pattern_list(pw->pw_name, arg, len, 0) != 1)
     518                 :            :                                 result = 0;
     519                 :            :                         else
     520                 :          0 :                                 debug("%.200s line %d: matched "
     521                 :            :                                     "'LocalUser %.100s' ",
     522                 :            :                                     filename, linenum, pw->pw_name);
     523         [ #  # ]:          0 :                 } else if (strcasecmp(attrib, "exec") == 0) {
     524         [ #  # ]:          0 :                         if (gethostname(thishost, sizeof(thishost)) == -1)
     525                 :          0 :                                 fatal("gethostname: %s", strerror(errno));
     526                 :          0 :                         strlcpy(shorthost, thishost, sizeof(shorthost));
     527                 :          0 :                         shorthost[strcspn(thishost, ".")] = '\0';
     528                 :            :                         snprintf(portstr, sizeof(portstr), "%d", port);
     529                 :            : 
     530                 :          0 :                         cmd = percent_expand(arg,
     531                 :            :                             "L", shorthost,
     532                 :            :                             "d", pw->pw_dir,
     533                 :            :                             "h", host,
     534                 :            :                             "l", thishost,
     535                 :            :                             "n", host_arg,
     536                 :            :                             "p", portstr,
     537                 :            :                             "r", ruser,
     538                 :            :                             "u", pw->pw_name,
     539                 :            :                             (char *)NULL);
     540         [ #  # ]:          0 :                         if (result != 1) {
     541                 :            :                                 /* skip execution if prior predicate failed */
     542                 :          0 :                                 debug("%.200s line %d: skipped exec \"%.100s\"",
     543                 :            :                                     filename, linenum, cmd);
     544                 :            :                         } else {
     545                 :          0 :                                 r = execute_in_shell(cmd);
     546         [ #  # ]:          0 :                                 if (r == -1) {
     547                 :          0 :                                         fatal("%.200s line %d: match exec "
     548                 :            :                                             "'%.100s' error", filename,
     549                 :            :                                             linenum, cmd);
     550         [ #  # ]:          0 :                                 } else if (r == 0) {
     551                 :          0 :                                         debug("%.200s line %d: matched "
     552                 :            :                                             "'exec \"%.100s\"'", filename,
     553                 :            :                                             linenum, cmd);
     554                 :            :                                 } else {
     555                 :          0 :                                         debug("%.200s line %d: no match "
     556                 :            :                                             "'exec \"%.100s\"'", filename,
     557                 :            :                                             linenum, cmd);
     558                 :          0 :                                         result = 0;
     559                 :            :                                 }
     560                 :            :                         }
     561                 :          0 :                         free(cmd);
     562                 :            :                 } else {
     563                 :          0 :                         error("Unsupported Match attribute %s", attrib);
     564                 :          0 :                         result = -1;
     565                 :            :                         goto out;
     566                 :            :                 }
     567                 :            :         }
     568         [ #  # ]:          0 :         if (attributes == 0) {
     569                 :          0 :                 error("One or more attributes required for Match");
     570                 :          0 :                 result = -1;
     571                 :            :                 goto out;
     572                 :            :         }
     573         [ #  # ]:          0 :         debug3("match %sfound", result ? "" : "not ");
     574                 :          0 :         *condition = cp;
     575                 :            :  out:
     576                 :          0 :         free(host);
     577                 :          0 :         return result;
     578                 :            : }
     579                 :            : 
     580                 :            : /* Check and prepare a domain name: removes trailing '.' and lowercases */
     581                 :            : static void
     582                 :          0 : valid_domain(char *name, const char *filename, int linenum)
     583                 :            : {
     584                 :          0 :         size_t i, l = strlen(name);
     585                 :          0 :         u_char c, last = '\0';
     586                 :            : 
     587         [ #  # ]:          0 :         if (l == 0)
     588                 :          0 :                 fatal("%s line %d: empty hostname suffix", filename, linenum);
     589         [ #  # ]:          0 :         if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
     590                 :          0 :                 fatal("%s line %d: hostname suffix \"%.100s\" "
     591                 :            :                     "starts with invalid character", filename, linenum, name);
     592         [ #  # ]:          0 :         for (i = 0; i < l; i++) {
     593                 :          0 :                 c = tolower((u_char)name[i]);
     594                 :          0 :                 name[i] = (char)c;
     595         [ #  # ]:          0 :                 if (last == '.' && c == '.')
     596                 :          0 :                         fatal("%s line %d: hostname suffix \"%.100s\" contains "
     597                 :            :                             "consecutive separators", filename, linenum, name);
     598 [ #  # ][ #  # ]:          0 :                 if (c != '.' && c != '-' && !isalnum(c) &&
                 [ #  # ]
     599                 :            :                     c != '_') /* technically invalid, but common */
     600                 :          0 :                         fatal("%s line %d: hostname suffix \"%.100s\" contains "
     601                 :            :                             "invalid characters", filename, linenum, name);
     602                 :          0 :                 last = c;
     603                 :            :         }
     604         [ #  # ]:          0 :         if (name[l - 1] == '.')
     605                 :          0 :                 name[l - 1] = '\0';
     606                 :          0 : }
     607                 :            : 
     608                 :            : /*
     609                 :            :  * Returns the number of the token pointed to by cp or oBadOption.
     610                 :            :  */
     611                 :            : static OpCodes
     612                 :      53852 : parse_token(const char *cp, const char *filename, int linenum,
     613                 :            :     const char *ignored_unknown)
     614                 :            : {
     615                 :            :         int i;
     616                 :            : 
     617         [ +  - ]:    1793153 :         for (i = 0; keywords[i].name; i++)
     618         [ +  + ]:    1793153 :                 if (strcmp(cp, keywords[i].name) == 0)
     619                 :      53852 :                         return keywords[i].opcode;
     620 [ #  # ][ #  # ]:          0 :         if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
     621                 :          0 :             strlen(ignored_unknown), 1) == 1)
     622                 :            :                 return oIgnoredUnknownOption;
     623                 :          0 :         error("%s: line %d: Bad configuration option: %s",
     624                 :            :             filename, linenum, cp);
     625                 :          0 :         return oBadOption;
     626                 :            : }
     627                 :            : 
     628                 :            : /* Multistate option parsing */
     629                 :            : struct multistate {
     630                 :            :         char *key;
     631                 :            :         int value;
     632                 :            : };
     633                 :            : static const struct multistate multistate_flag[] = {
     634                 :            :         { "true",                     1 },
     635                 :            :         { "false",                    0 },
     636                 :            :         { "yes",                      1 },
     637                 :            :         { "no",                               0 },
     638                 :            :         { NULL, -1 }
     639                 :            : };
     640                 :            : static const struct multistate multistate_yesnoask[] = {
     641                 :            :         { "true",                     1 },
     642                 :            :         { "false",                    0 },
     643                 :            :         { "yes",                      1 },
     644                 :            :         { "no",                               0 },
     645                 :            :         { "ask",                      2 },
     646                 :            :         { NULL, -1 }
     647                 :            : };
     648                 :            : static const struct multistate multistate_addressfamily[] = {
     649                 :            :         { "inet",                     AF_INET },
     650                 :            :         { "inet6",                    AF_INET6 },
     651                 :            :         { "any",                      AF_UNSPEC },
     652                 :            :         { NULL, -1 }
     653                 :            : };
     654                 :            : static const struct multistate multistate_controlmaster[] = {
     655                 :            :         { "true",                     SSHCTL_MASTER_YES },
     656                 :            :         { "yes",                      SSHCTL_MASTER_YES },
     657                 :            :         { "false",                    SSHCTL_MASTER_NO },
     658                 :            :         { "no",                               SSHCTL_MASTER_NO },
     659                 :            :         { "auto",                     SSHCTL_MASTER_AUTO },
     660                 :            :         { "ask",                      SSHCTL_MASTER_ASK },
     661                 :            :         { "autoask",                  SSHCTL_MASTER_AUTO_ASK },
     662                 :            :         { NULL, -1 }
     663                 :            : };
     664                 :            : static const struct multistate multistate_tunnel[] = {
     665                 :            :         { "ethernet",                 SSH_TUNMODE_ETHERNET },
     666                 :            :         { "point-to-point",           SSH_TUNMODE_POINTOPOINT },
     667                 :            :         { "true",                     SSH_TUNMODE_DEFAULT },
     668                 :            :         { "yes",                      SSH_TUNMODE_DEFAULT },
     669                 :            :         { "false",                    SSH_TUNMODE_NO },
     670                 :            :         { "no",                               SSH_TUNMODE_NO },
     671                 :            :         { NULL, -1 }
     672                 :            : };
     673                 :            : static const struct multistate multistate_requesttty[] = {
     674                 :            :         { "true",                     REQUEST_TTY_YES },
     675                 :            :         { "yes",                      REQUEST_TTY_YES },
     676                 :            :         { "false",                    REQUEST_TTY_NO },
     677                 :            :         { "no",                               REQUEST_TTY_NO },
     678                 :            :         { "force",                    REQUEST_TTY_FORCE },
     679                 :            :         { "auto",                     REQUEST_TTY_AUTO },
     680                 :            :         { NULL, -1 }
     681                 :            : };
     682                 :            : static const struct multistate multistate_canonicalizehostname[] = {
     683                 :            :         { "true",                     SSH_CANONICALISE_YES },
     684                 :            :         { "false",                    SSH_CANONICALISE_NO },
     685                 :            :         { "yes",                      SSH_CANONICALISE_YES },
     686                 :            :         { "no",                               SSH_CANONICALISE_NO },
     687                 :            :         { "always",                   SSH_CANONICALISE_ALWAYS },
     688                 :            :         { NULL, -1 }
     689                 :            : };
     690                 :            : 
     691                 :            : /*
     692                 :            :  * Processes a single option line as used in the configuration files. This
     693                 :            :  * only sets those values that have not already been set.
     694                 :            :  */
     695                 :            : #define WHITESPACE " \t\r\n"
     696                 :            : int
     697                 :      53852 : process_config_line(Options *options, struct passwd *pw, const char *host,
     698                 :            :     char *line, const char *filename, int linenum, int *activep, int userconfig)
     699                 :            : {
     700                 :            :         char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
     701                 :            :         char **cpptr, fwdarg[256];
     702                 :      53852 :         u_int i, *uintptr, max_entries = 0;
     703                 :      53852 :         int negated, opcode, *intptr, value, value2, cmdline = 0;
     704                 :            :         LogLevel *log_level_ptr;
     705                 :            :         long long val64;
     706                 :            :         size_t len;
     707                 :            :         Forward fwd;
     708                 :            :         const struct multistate *multistate_ptr;
     709                 :            :         struct allowed_cname *cname;
     710                 :            : 
     711         [ +  + ]:      53852 :         if (activep == NULL) { /* We are processing a command line directive */
     712                 :       1290 :                 cmdline = 1;
     713                 :       1290 :                 activep = &cmdline;
     714                 :            :         }
     715                 :            : 
     716                 :            :         /* Strip trailing whitespace */
     717         [ +  - ]:     106414 :         for (len = strlen(line) - 1; len > 0; len--) {
     718         [ +  + ]:     106414 :                 if (strchr(WHITESPACE, line[len]) == NULL)
     719                 :            :                         break;
     720                 :      52562 :                 line[len] = '\0';
     721                 :            :         }
     722                 :            : 
     723                 :      53852 :         s = line;
     724                 :            :         /* Get the keyword. (Each line is supposed to begin with a keyword). */
     725         [ +  - ]:      53852 :         if ((keyword = strdelim(&s)) == NULL)
     726                 :            :                 return 0;
     727                 :            :         /* Ignore leading whitespace. */
     728         [ +  + ]:      53852 :         if (*keyword == '\0')
     729                 :      41864 :                 keyword = strdelim(&s);
     730 [ +  - ][ +  - ]:      53852 :         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
         [ +  - ][ +  - ]
     731                 :            :                 return 0;
     732                 :            :         /* Match lowercase keyword */
     733                 :      53852 :         lowercase(keyword);
     734                 :            : 
     735                 :      53852 :         opcode = parse_token(keyword, filename, linenum,
     736                 :      53852 :             options->ignored_unknown);
     737                 :            : 
     738   [ +  -  -  +  :      53852 :         switch (opcode) {
          +  -  -  -  +  
          -  +  -  -  +  
          +  +  +  +  -  
          -  +  -  -  +  
          +  -  -  -  -  
          +  +  -  +  +  
          +  +  +  -  -  
          -  +  +  +  -  
          +  +  +  -  +  
          +  +  +  +  -  
          -  -  -  -  +  
          +  +  -  -  -  
          -  -  +  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  - ]
     739                 :            :         case oBadOption:
     740                 :            :                 /* don't panic, but count bad options */
     741                 :            :                 return -1;
     742                 :            :                 /* NOTREACHED */
     743                 :            :         case oIgnoredUnknownOption:
     744                 :          0 :                 debug("%s line %d: Ignored unknown option \"%s\"",
     745                 :            :                     filename, linenum, keyword);
     746                 :          0 :                 return 0;
     747                 :            :         case oConnectTimeout:
     748                 :          0 :                 intptr = &options->connection_timeout;
     749                 :            : parse_time:
     750                 :        222 :                 arg = strdelim(&s);
     751 [ +  - ][ -  + ]:        222 :                 if (!arg || *arg == '\0')
     752                 :          0 :                         fatal("%s line %d: missing time value.",
     753                 :            :                             filename, linenum);
     754         [ -  + ]:        222 :                 if ((value = convtime(arg)) == -1)
     755                 :          0 :                         fatal("%s line %d: invalid time value.",
     756                 :            :                             filename, linenum);
     757 [ +  - ][ +  - ]:        222 :                 if (*activep && *intptr == -1)
     758                 :        222 :                         *intptr = value;
     759                 :            :                 break;
     760                 :            : 
     761                 :            :         case oForwardAgent:
     762                 :          2 :                 intptr = &options->forward_agent;
     763                 :            :  parse_flag:
     764                 :            :                 multistate_ptr = multistate_flag;
     765                 :            :  parse_multistate:
     766                 :      21139 :                 arg = strdelim(&s);
     767 [ +  - ][ +  - ]:      21139 :                 if (!arg || *arg == '\0')
     768                 :          0 :                         fatal("%s line %d: missing argument.",
     769                 :            :                             filename, linenum);
     770                 :            :                 value = -1;
     771         [ +  - ]:      73971 :                 for (i = 0; multistate_ptr[i].key != NULL; i++) {
     772         [ +  + ]:      73971 :                         if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
     773                 :      21139 :                                 value = multistate_ptr[i].value;
     774                 :      21139 :                                 break;
     775                 :            :                         }
     776                 :            :                 }
     777         [ -  + ]:      21139 :                 if (value == -1)
     778                 :          0 :                         fatal("%s line %d: unsupported option \"%s\".",
     779                 :            :                             filename, linenum, arg);
     780 [ +  - ][ +  + ]:      21139 :                 if (*activep && *intptr == -1)
     781                 :      10651 :                         *intptr = value;
     782                 :            :                 break;
     783                 :            : 
     784                 :            :         case oForwardX11:
     785                 :          1 :                 intptr = &options->forward_x11;
     786                 :          1 :                 goto parse_flag;
     787                 :            : 
     788                 :            :         case oForwardX11Trusted:
     789                 :          0 :                 intptr = &options->forward_x11_trusted;
     790                 :          0 :                 goto parse_flag;
     791                 :            :         
     792                 :            :         case oForwardX11Timeout:
     793                 :          0 :                 intptr = &options->forward_x11_timeout;
     794                 :          0 :                 goto parse_time;
     795                 :            : 
     796                 :            :         case oGatewayPorts:
     797                 :          0 :                 intptr = &options->gateway_ports;
     798                 :          0 :                 goto parse_flag;
     799                 :            : 
     800                 :            :         case oExitOnForwardFailure:
     801                 :        105 :                 intptr = &options->exit_on_forward_failure;
     802                 :        105 :                 goto parse_flag;
     803                 :            : 
     804                 :            :         case oUsePrivilegedPort:
     805                 :          0 :                 intptr = &options->use_privileged_port;
     806                 :          0 :                 goto parse_flag;
     807                 :            : 
     808                 :            :         case oPasswordAuthentication:
     809                 :       2616 :                 intptr = &options->password_authentication;
     810                 :       2616 :                 goto parse_flag;
     811                 :            : 
     812                 :            :         case oKbdInteractiveAuthentication:
     813                 :          0 :                 intptr = &options->kbd_interactive_authentication;
     814                 :          0 :                 goto parse_flag;
     815                 :            : 
     816                 :            :         case oKbdInteractiveDevices:
     817                 :          0 :                 charptr = &options->kbd_interactive_devices;
     818                 :          0 :                 goto parse_string;
     819                 :            : 
     820                 :            :         case oPubkeyAuthentication:
     821                 :       2616 :                 intptr = &options->pubkey_authentication;
     822                 :       2616 :                 goto parse_flag;
     823                 :            : 
     824                 :            :         case oRSAAuthentication:
     825                 :       2616 :                 intptr = &options->rsa_authentication;
     826                 :       2616 :                 goto parse_flag;
     827                 :            : 
     828                 :            :         case oRhostsRSAAuthentication:
     829                 :       2616 :                 intptr = &options->rhosts_rsa_authentication;
     830                 :       2616 :                 goto parse_flag;
     831                 :            : 
     832                 :            :         case oHostbasedAuthentication:
     833                 :       2616 :                 intptr = &options->hostbased_authentication;
     834                 :       2616 :                 goto parse_flag;
     835                 :            : 
     836                 :            :         case oChallengeResponseAuthentication:
     837                 :       2616 :                 intptr = &options->challenge_response_authentication;
     838                 :       2616 :                 goto parse_flag;
     839                 :            : 
     840                 :            :         case oGssAuthentication:
     841                 :          0 :                 intptr = &options->gss_authentication;
     842                 :          0 :                 goto parse_flag;
     843                 :            : 
     844                 :            :         case oGssDelegateCreds:
     845                 :          0 :                 intptr = &options->gss_deleg_creds;
     846                 :          0 :                 goto parse_flag;
     847                 :            : 
     848                 :            :         case oBatchMode:
     849                 :       2616 :                 intptr = &options->batch_mode;
     850                 :       2616 :                 goto parse_flag;
     851                 :            : 
     852                 :            :         case oCheckHostIP:
     853                 :          0 :                 intptr = &options->check_host_ip;
     854                 :          0 :                 goto parse_flag;
     855                 :            : 
     856                 :            :         case oVerifyHostKeyDNS:
     857                 :          0 :                 intptr = &options->verify_host_key_dns;
     858                 :          0 :                 multistate_ptr = multistate_yesnoask;
     859                 :          0 :                 goto parse_multistate;
     860                 :            : 
     861                 :            :         case oStrictHostKeyChecking:
     862                 :       2616 :                 intptr = &options->strict_host_key_checking;
     863                 :       2616 :                 multistate_ptr = multistate_yesnoask;
     864                 :       2616 :                 goto parse_multistate;
     865                 :            : 
     866                 :            :         case oCompression:
     867                 :         85 :                 intptr = &options->compression;
     868                 :         85 :                 goto parse_flag;
     869                 :            : 
     870                 :            :         case oTCPKeepAlive:
     871                 :          0 :                 intptr = &options->tcp_keep_alive;
     872                 :          0 :                 goto parse_flag;
     873                 :            : 
     874                 :            :         case oNoHostAuthenticationForLocalhost:
     875                 :          0 :                 intptr = &options->no_host_authentication_for_localhost;
     876                 :          0 :                 goto parse_flag;
     877                 :            : 
     878                 :            :         case oNumberOfPasswordPrompts:
     879                 :          0 :                 intptr = &options->number_of_password_prompts;
     880                 :          0 :                 goto parse_int;
     881                 :            : 
     882                 :            :         case oCompressionLevel:
     883                 :          0 :                 intptr = &options->compression_level;
     884                 :          0 :                 goto parse_int;
     885                 :            : 
     886                 :            :         case oRekeyLimit:
     887                 :         79 :                 arg = strdelim(&s);
     888 [ +  - ][ -  + ]:         79 :                 if (!arg || *arg == '\0')
     889                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename,
     890                 :            :                             linenum);
     891         [ +  + ]:         79 :                 if (strcmp(arg, "default") == 0) {
     892                 :          4 :                         val64 = 0;
     893                 :            :                 } else {
     894         [ -  + ]:         75 :                         if (scan_scaled(arg, &val64) == -1)
     895                 :          0 :                                 fatal("%.200s line %d: Bad number '%s': %s",
     896                 :          0 :                                     filename, linenum, arg, strerror(errno));
     897                 :            :                         /* check for too-large or too-small limits */
     898         [ -  + ]:         75 :                         if (val64 > UINT_MAX)
     899                 :          0 :                                 fatal("%.200s line %d: RekeyLimit too large",
     900                 :            :                                     filename, linenum);
     901         [ -  + ]:         75 :                         if (val64 != 0 && val64 < 16)
     902                 :          0 :                                 fatal("%.200s line %d: RekeyLimit too small",
     903                 :            :                                     filename, linenum);
     904                 :            :                 }
     905 [ +  - ][ +  - ]:         79 :                 if (*activep && options->rekey_limit == -1)
     906                 :         79 :                         options->rekey_limit = (u_int32_t)val64;
     907         [ +  + ]:         79 :                 if (s != NULL) { /* optional rekey interval present */
     908         [ -  + ]:          4 :                         if (strcmp(s, "none") == 0) {
     909                 :          0 :                                 (void)strdelim(&s); /* discard */
     910                 :          0 :                                 break;
     911                 :            :                         }
     912                 :          4 :                         intptr = &options->rekey_interval;
     913                 :          4 :                         goto parse_time;
     914                 :            :                 }
     915                 :            :                 break;
     916                 :            : 
     917                 :            :         case oIdentityFile:
     918                 :       5190 :                 arg = strdelim(&s);
     919 [ +  - ][ -  + ]:       5190 :                 if (!arg || *arg == '\0')
     920                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
     921         [ +  - ]:       5190 :                 if (*activep) {
     922                 :       5190 :                         intptr = &options->num_identity_files;
     923         [ -  + ]:       5190 :                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
     924                 :          0 :                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
     925                 :            :                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
     926                 :       5190 :                         add_identity_file(options, NULL, arg, userconfig);
     927                 :            :                 }
     928                 :            :                 break;
     929                 :            : 
     930                 :            :         case oXAuthLocation:
     931                 :          0 :                 charptr=&options->xauth_location;
     932                 :          0 :                 goto parse_string;
     933                 :            : 
     934                 :            :         case oUser:
     935                 :       2616 :                 charptr = &options->user;
     936                 :            : parse_string:
     937                 :       7850 :                 arg = strdelim(&s);
     938 [ +  - ][ -  + ]:       7850 :                 if (!arg || *arg == '\0')
     939                 :          0 :                         fatal("%.200s line %d: Missing argument.",
     940                 :            :                             filename, linenum);
     941 [ +  - ][ +  + ]:       7850 :                 if (*activep && *charptr == NULL)
     942                 :       3924 :                         *charptr = xstrdup(arg);
     943                 :            :                 break;
     944                 :            : 
     945                 :            :         case oGlobalKnownHostsFile:
     946                 :       2678 :                 cpptr = (char **)&options->system_hostfiles;
     947                 :       2678 :                 uintptr = &options->num_system_hostfiles;
     948                 :       2678 :                 max_entries = SSH_MAX_HOSTS_FILES;
     949                 :            : parse_char_array:
     950 [ +  - ][ +  + ]:       5356 :                 if (*activep && *uintptr == 0) {
     951 [ +  + ][ +  - ]:       5232 :                         while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
     952         [ -  + ]:       2616 :                                 if ((*uintptr) >= max_entries)
     953                 :          0 :                                         fatal("%s line %d: "
     954                 :            :                                             "too many authorized keys files.",
     955                 :            :                                             filename, linenum);
     956                 :       2616 :                                 cpptr[(*uintptr)++] = xstrdup(arg);
     957                 :            :                         }
     958                 :            :                 }
     959                 :            :                 return 0;
     960                 :            : 
     961                 :            :         case oUserKnownHostsFile:
     962                 :       2678 :                 cpptr = (char **)&options->user_hostfiles;
     963                 :       2678 :                 uintptr = &options->num_user_hostfiles;
     964                 :       2678 :                 max_entries = SSH_MAX_HOSTS_FILES;
     965                 :       2678 :                 goto parse_char_array;
     966                 :            : 
     967                 :            :         case oHostName:
     968                 :       2616 :                 charptr = &options->hostname;
     969                 :       2616 :                 goto parse_string;
     970                 :            : 
     971                 :            :         case oHostKeyAlias:
     972                 :       2616 :                 charptr = &options->host_key_alias;
     973                 :       2616 :                 goto parse_string;
     974                 :            : 
     975                 :            :         case oPreferredAuthentications:
     976                 :          0 :                 charptr = &options->preferred_authentications;
     977                 :          0 :                 goto parse_string;
     978                 :            : 
     979                 :            :         case oBindAddress:
     980                 :          0 :                 charptr = &options->bind_address;
     981                 :          0 :                 goto parse_string;
     982                 :            : 
     983                 :            :         case oPKCS11Provider:
     984                 :          0 :                 charptr = &options->pkcs11_provider;
     985                 :          0 :                 goto parse_string;
     986                 :            : 
     987                 :            :         case oProxyCommand:
     988                 :       2611 :                 charptr = &options->proxy_command;
     989                 :            : parse_command:
     990         [ -  + ]:       2619 :                 if (s == NULL)
     991                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
     992                 :       2619 :                 len = strspn(s, WHITESPACE "=");
     993 [ +  - ][ +  + ]:       2619 :                 if (*activep && *charptr == NULL)
     994                 :       1205 :                         *charptr = xstrdup(s + len);
     995                 :            :                 return 0;
     996                 :            : 
     997                 :            :         case oPort:
     998                 :       2616 :                 intptr = &options->port;
     999                 :            : parse_int:
    1000                 :       2866 :                 arg = strdelim(&s);
    1001 [ +  - ][ -  + ]:       2866 :                 if (!arg || *arg == '\0')
    1002                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
    1003         [ -  + ]:       2866 :                 if (arg[0] < '0' || arg[0] > '9')
    1004                 :          0 :                         fatal("%.200s line %d: Bad number.", filename, linenum);
    1005                 :            : 
    1006                 :            :                 /* Octal, decimal, or hex format? */
    1007                 :       2866 :                 value = strtol(arg, &endofnumber, 0);
    1008         [ -  + ]:       2866 :                 if (arg == endofnumber)
    1009                 :          0 :                         fatal("%.200s line %d: Bad number.", filename, linenum);
    1010 [ +  - ][ +  + ]:       2866 :                 if (*activep && *intptr == -1)
    1011                 :       1507 :                         *intptr = value;
    1012                 :            :                 break;
    1013                 :            : 
    1014                 :            :         case oConnectionAttempts:
    1015                 :         32 :                 intptr = &options->connection_attempts;
    1016                 :         32 :                 goto parse_int;
    1017                 :            : 
    1018                 :            :         case oCipher:
    1019                 :          0 :                 intptr = &options->cipher;
    1020                 :          0 :                 arg = strdelim(&s);
    1021 [ #  # ][ #  # ]:          0 :                 if (!arg || *arg == '\0')
    1022                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
    1023                 :          0 :                 value = cipher_number(arg);
    1024         [ #  # ]:          0 :                 if (value == -1)
    1025         [ #  # ]:          0 :                         fatal("%.200s line %d: Bad cipher '%s'.",
    1026                 :            :                             filename, linenum, arg ? arg : "<NONE>");
    1027 [ #  # ][ #  # ]:          0 :                 if (*activep && *intptr == -1)
    1028                 :          0 :                         *intptr = value;
    1029                 :            :                 break;
    1030                 :            : 
    1031                 :            :         case oCiphers:
    1032                 :         43 :                 arg = strdelim(&s);
    1033 [ +  - ][ -  + ]:         43 :                 if (!arg || *arg == '\0')
    1034                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
    1035         [ -  + ]:         43 :                 if (!ciphers_valid(arg))
    1036         [ #  # ]:          0 :                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
    1037                 :            :                             filename, linenum, arg ? arg : "<NONE>");
    1038 [ +  - ][ +  - ]:         43 :                 if (*activep && options->ciphers == NULL)
    1039                 :         43 :                         options->ciphers = xstrdup(arg);
    1040                 :            :                 break;
    1041                 :            : 
    1042                 :            :         case oMacs:
    1043                 :         19 :                 arg = strdelim(&s);
    1044 [ +  - ][ -  + ]:         19 :                 if (!arg || *arg == '\0')
    1045                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
    1046         [ -  + ]:         19 :                 if (!mac_valid(arg))
    1047         [ #  # ]:          0 :                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
    1048                 :            :                             filename, linenum, arg ? arg : "<NONE>");
    1049 [ +  - ][ +  - ]:         19 :                 if (*activep && options->macs == NULL)
    1050                 :         19 :                         options->macs = xstrdup(arg);
    1051                 :            :                 break;
    1052                 :            : 
    1053                 :            :         case oKexAlgorithms:
    1054                 :        508 :                 arg = strdelim(&s);
    1055 [ +  - ][ -  + ]:        508 :                 if (!arg || *arg == '\0')
    1056                 :          0 :                         fatal("%.200s line %d: Missing argument.",
    1057                 :            :                             filename, linenum);
    1058         [ -  + ]:        508 :                 if (!kex_names_valid(arg))
    1059         [ #  # ]:          0 :                         fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
    1060                 :            :                             filename, linenum, arg ? arg : "<NONE>");
    1061 [ +  - ][ +  + ]:        508 :                 if (*activep && options->kex_algorithms == NULL)
    1062                 :        290 :                         options->kex_algorithms = xstrdup(arg);
    1063                 :            :                 break;
    1064                 :            : 
    1065                 :            :         case oHostKeyAlgorithms:
    1066                 :          0 :                 arg = strdelim(&s);
    1067 [ #  # ][ #  # ]:          0 :                 if (!arg || *arg == '\0')
    1068                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
    1069         [ #  # ]:          0 :                 if (!key_names_valid2(arg))
    1070         [ #  # ]:          0 :                         fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
    1071                 :            :                             filename, linenum, arg ? arg : "<NONE>");
    1072 [ #  # ][ #  # ]:          0 :                 if (*activep && options->hostkeyalgorithms == NULL)
    1073                 :          0 :                         options->hostkeyalgorithms = xstrdup(arg);
    1074                 :            :                 break;
    1075                 :            : 
    1076                 :            :         case oProtocol:
    1077                 :       2695 :                 intptr = &options->protocol;
    1078                 :       2695 :                 arg = strdelim(&s);
    1079 [ +  - ][ -  + ]:       2695 :                 if (!arg || *arg == '\0')
    1080                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
    1081                 :       2695 :                 value = proto_spec(arg);
    1082         [ -  + ]:       2695 :                 if (value == SSH_PROTO_UNKNOWN)
    1083         [ #  # ]:          0 :                         fatal("%.200s line %d: Bad protocol spec '%s'.",
    1084                 :            :                             filename, linenum, arg ? arg : "<NONE>");
    1085 [ +  - ][ +  + ]:       2695 :                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
    1086                 :        294 :                         *intptr = value;
    1087                 :            :                 break;
    1088                 :            : 
    1089                 :            :         case oLogLevel:
    1090                 :       2616 :                 log_level_ptr = &options->log_level;
    1091                 :       2616 :                 arg = strdelim(&s);
    1092                 :       2616 :                 value = log_level_number(arg);
    1093         [ -  + ]:       2616 :                 if (value == SYSLOG_LEVEL_NOT_SET)
    1094         [ #  # ]:          0 :                         fatal("%.200s line %d: unsupported log level '%s'",
    1095                 :            :                             filename, linenum, arg ? arg : "<NONE>");
    1096 [ +  - ][ +  + ]:       2616 :                 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
    1097                 :       1169 :                         *log_level_ptr = (LogLevel) value;
    1098                 :            :                 break;
    1099                 :            : 
    1100                 :            :         case oLocalForward:
    1101                 :            :         case oRemoteForward:
    1102                 :            :         case oDynamicForward:
    1103                 :         16 :                 arg = strdelim(&s);
    1104 [ +  - ][ -  + ]:         16 :                 if (arg == NULL || *arg == '\0')
    1105                 :          0 :                         fatal("%.200s line %d: Missing port argument.",
    1106                 :            :                             filename, linenum);
    1107                 :            : 
    1108         [ +  - ]:         16 :                 if (opcode == oLocalForward ||
    1109                 :            :                     opcode == oRemoteForward) {
    1110                 :         16 :                         arg2 = strdelim(&s);
    1111 [ +  - ][ -  + ]:         16 :                         if (arg2 == NULL || *arg2 == '\0')
    1112                 :          0 :                                 fatal("%.200s line %d: Missing target argument.",
    1113                 :            :                                     filename, linenum);
    1114                 :            : 
    1115                 :            :                         /* construct a string for parse_forward */
    1116                 :            :                         snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
    1117         [ #  # ]:          0 :                 } else if (opcode == oDynamicForward) {
    1118                 :          0 :                         strlcpy(fwdarg, arg, sizeof(fwdarg));
    1119                 :            :                 }
    1120                 :            : 
    1121         [ -  + ]:         16 :                 if (parse_forward(&fwd, fwdarg,
    1122                 :            :                     opcode == oDynamicForward ? 1 : 0,
    1123                 :            :                     opcode == oRemoteForward ? 1 : 0) == 0)
    1124                 :          0 :                         fatal("%.200s line %d: Bad forwarding specification.",
    1125                 :            :                             filename, linenum);
    1126                 :            : 
    1127         [ +  - ]:         16 :                 if (*activep) {
    1128         [ +  + ]:         16 :                         if (opcode == oLocalForward ||
    1129                 :            :                             opcode == oDynamicForward)
    1130                 :          8 :                                 add_local_forward(options, &fwd);
    1131         [ +  - ]:          8 :                         else if (opcode == oRemoteForward)
    1132                 :          8 :                                 add_remote_forward(options, &fwd);
    1133                 :            :                 }
    1134                 :            :                 break;
    1135                 :            : 
    1136                 :            :         case oClearAllForwardings:
    1137                 :          8 :                 intptr = &options->clear_forwardings;
    1138                 :          8 :                 goto parse_flag;
    1139                 :            : 
    1140                 :            :         case oHost:
    1141         [ -  + ]:       2624 :                 if (cmdline)
    1142                 :          0 :                         fatal("Host directive not supported as a command-line "
    1143                 :            :                             "option");
    1144                 :       2624 :                 *activep = 0;
    1145                 :       2624 :                 arg2 = NULL;
    1146 [ +  + ][ +  - ]:       7872 :                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    1147                 :       2624 :                         negated = *arg == '!';
    1148         [ -  + ]:       2624 :                         if (negated)
    1149                 :          0 :                                 arg++;
    1150         [ +  + ]:       2624 :                         if (match_pattern(host, arg)) {
    1151         [ -  + ]:       2616 :                                 if (negated) {
    1152                 :          0 :                                         debug("%.200s line %d: Skipping Host "
    1153                 :            :                                             "block because of negated match "
    1154                 :            :                                             "for %.100s", filename, linenum,
    1155                 :            :                                             arg);
    1156                 :          0 :                                         *activep = 0;
    1157                 :          0 :                                         break;
    1158                 :            :                                 }
    1159         [ +  - ]:       2616 :                                 if (!*activep)
    1160                 :       2616 :                                         arg2 = arg; /* logged below */
    1161                 :       5240 :                                 *activep = 1;
    1162                 :            :                         }
    1163                 :            :                 }
    1164         [ +  + ]:       2624 :                 if (*activep)
    1165                 :       2616 :                         debug("%.200s line %d: Applying options for %.100s",
    1166                 :            :                             filename, linenum, arg2);
    1167                 :            :                 /* Avoid garbage check below, as strdelim is done. */
    1168                 :            :                 return 0;
    1169                 :            : 
    1170                 :            :         case oMatch:
    1171         [ #  # ]:          0 :                 if (cmdline)
    1172                 :          0 :                         fatal("Host directive not supported as a command-line "
    1173                 :            :                             "option");
    1174                 :          0 :                 value = match_cfg_line(options, &s, pw, host,
    1175                 :            :                     filename, linenum);
    1176         [ #  # ]:          0 :                 if (value < 0)
    1177                 :          0 :                         fatal("%.200s line %d: Bad Match condition", filename,
    1178                 :            :                             linenum);
    1179                 :          0 :                 *activep = value;
    1180                 :          0 :                 break;
    1181                 :            : 
    1182                 :            :         case oEscapeChar:
    1183                 :          0 :                 intptr = &options->escape_char;
    1184                 :          0 :                 arg = strdelim(&s);
    1185 [ #  # ][ #  # ]:          0 :                 if (!arg || *arg == '\0')
    1186                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
    1187 [ #  # ][ #  # ]:          0 :                 if (arg[0] == '^' && arg[2] == 0 &&
                 [ #  # ]
    1188         [ #  # ]:          0 :                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
    1189                 :          0 :                         value = (u_char) arg[1] & 31;
    1190         [ #  # ]:          0 :                 else if (strlen(arg) == 1)
    1191                 :          0 :                         value = (u_char) arg[0];
    1192         [ #  # ]:          0 :                 else if (strcmp(arg, "none") == 0)
    1193                 :            :                         value = SSH_ESCAPECHAR_NONE;
    1194                 :            :                 else {
    1195                 :          0 :                         fatal("%.200s line %d: Bad escape character.",
    1196                 :            :                             filename, linenum);
    1197                 :            :                         /* NOTREACHED */
    1198                 :            :                         value = 0;      /* Avoid compiler warning. */
    1199                 :            :                 }
    1200 [ #  # ][ #  # ]:          0 :                 if (*activep && *intptr == -1)
    1201                 :          0 :                         *intptr = value;
    1202                 :            :                 break;
    1203                 :            : 
    1204                 :            :         case oAddressFamily:
    1205                 :          0 :                 intptr = &options->address_family;
    1206                 :          0 :                 multistate_ptr = multistate_addressfamily;
    1207                 :          0 :                 goto parse_multistate;
    1208                 :            : 
    1209                 :            :         case oEnableSSHKeysign:
    1210                 :          0 :                 intptr = &options->enable_ssh_keysign;
    1211                 :          0 :                 goto parse_flag;
    1212                 :            : 
    1213                 :            :         case oIdentitiesOnly:
    1214                 :          0 :                 intptr = &options->identities_only;
    1215                 :          0 :                 goto parse_flag;
    1216                 :            : 
    1217                 :            :         case oServerAliveInterval:
    1218                 :        218 :                 intptr = &options->server_alive_interval;
    1219                 :        218 :                 goto parse_time;
    1220                 :            : 
    1221                 :            :         case oServerAliveCountMax:
    1222                 :        218 :                 intptr = &options->server_alive_count_max;
    1223                 :        218 :                 goto parse_int;
    1224                 :            : 
    1225                 :            :         case oSendEnv:
    1226 [ +  + ][ +  - ]:         28 :                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    1227         [ -  + ]:         14 :                         if (strchr(arg, '=') != NULL)
    1228                 :          0 :                                 fatal("%s line %d: Invalid environment name.",
    1229                 :            :                                     filename, linenum);
    1230         [ +  + ]:         14 :                         if (!*activep)
    1231                 :          8 :                                 continue;
    1232         [ -  + ]:          6 :                         if (options->num_send_env >= MAX_SEND_ENV)
    1233                 :          0 :                                 fatal("%s line %d: too many send env.",
    1234                 :            :                                     filename, linenum);
    1235                 :         14 :                         options->send_env[options->num_send_env++] =
    1236                 :          6 :                             xstrdup(arg);
    1237                 :            :                 }
    1238                 :            :                 break;
    1239                 :            : 
    1240                 :            :         case oControlPath:
    1241                 :          2 :                 charptr = &options->control_path;
    1242                 :          2 :                 goto parse_string;
    1243                 :            : 
    1244                 :            :         case oControlMaster:
    1245                 :          0 :                 intptr = &options->control_master;
    1246                 :          0 :                 multistate_ptr = multistate_controlmaster;
    1247                 :          0 :                 goto parse_multistate;
    1248                 :            : 
    1249                 :            :         case oControlPersist:
    1250                 :            :                 /* no/false/yes/true, or a time spec */
    1251                 :          0 :                 intptr = &options->control_persist;
    1252                 :          0 :                 arg = strdelim(&s);
    1253 [ #  # ][ #  # ]:          0 :                 if (!arg || *arg == '\0')
    1254                 :          0 :                         fatal("%.200s line %d: Missing ControlPersist"
    1255                 :            :                             " argument.", filename, linenum);
    1256                 :          0 :                 value = 0;
    1257                 :          0 :                 value2 = 0;     /* timeout */
    1258 [ #  # ][ #  # ]:          0 :                 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
         [ #  # ][ #  # ]
    1259                 :            :                         value = 0;
    1260 [ #  # ][ #  # ]:          0 :                 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
         [ #  # ][ #  # ]
                 [ #  # ]
    1261                 :            :                         value = 1;
    1262         [ #  # ]:          0 :                 else if ((value2 = convtime(arg)) >= 0)
    1263                 :            :                         value = 1;
    1264                 :            :                 else
    1265                 :          0 :                         fatal("%.200s line %d: Bad ControlPersist argument.",
    1266                 :            :                             filename, linenum);
    1267 [ #  # ][ #  # ]:          0 :                 if (*activep && *intptr == -1) {
    1268                 :          0 :                         *intptr = value;
    1269                 :          0 :                         options->control_persist_timeout = value2;
    1270                 :            :                 }
    1271                 :            :                 break;
    1272                 :            : 
    1273                 :            :         case oHashKnownHosts:
    1274                 :          0 :                 intptr = &options->hash_known_hosts;
    1275                 :          0 :                 goto parse_flag;
    1276                 :            : 
    1277                 :            :         case oTunnel:
    1278                 :          0 :                 intptr = &options->tun_open;
    1279                 :          0 :                 multistate_ptr = multistate_tunnel;
    1280                 :          0 :                 goto parse_multistate;
    1281                 :            : 
    1282                 :            :         case oTunnelDevice:
    1283                 :          0 :                 arg = strdelim(&s);
    1284 [ #  # ][ #  # ]:          0 :                 if (!arg || *arg == '\0')
    1285                 :          0 :                         fatal("%.200s line %d: Missing argument.", filename, linenum);
    1286                 :          0 :                 value = a2tun(arg, &value2);
    1287         [ #  # ]:          0 :                 if (value == SSH_TUNID_ERR)
    1288                 :          0 :                         fatal("%.200s line %d: Bad tun device.", filename, linenum);
    1289         [ #  # ]:          0 :                 if (*activep) {
    1290                 :          0 :                         options->tun_local = value;
    1291                 :          0 :                         options->tun_remote = value2;
    1292                 :            :                 }
    1293                 :            :                 break;
    1294                 :            : 
    1295                 :            :         case oLocalCommand:
    1296                 :          8 :                 charptr = &options->local_command;
    1297                 :          8 :                 goto parse_command;
    1298                 :            : 
    1299                 :            :         case oPermitLocalCommand:
    1300                 :         10 :                 intptr = &options->permit_local_command;
    1301                 :         10 :                 goto parse_flag;
    1302                 :            : 
    1303                 :            :         case oVisualHostKey:
    1304                 :          0 :                 intptr = &options->visual_host_key;
    1305                 :          0 :                 goto parse_flag;
    1306                 :            : 
    1307                 :            :         case oIPQoS:
    1308                 :          0 :                 arg = strdelim(&s);
    1309         [ #  # ]:          0 :                 if ((value = parse_ipqos(arg)) == -1)
    1310                 :          0 :                         fatal("%s line %d: Bad IPQoS value: %s",
    1311                 :            :                             filename, linenum, arg);
    1312                 :          0 :                 arg = strdelim(&s);
    1313         [ #  # ]:          0 :                 if (arg == NULL)
    1314                 :          0 :                         value2 = value;
    1315         [ #  # ]:          0 :                 else if ((value2 = parse_ipqos(arg)) == -1)
    1316                 :          0 :                         fatal("%s line %d: Bad IPQoS value: %s",
    1317                 :            :                             filename, linenum, arg);
    1318         [ #  # ]:          0 :                 if (*activep) {
    1319                 :          0 :                         options->ip_qos_interactive = value;
    1320                 :          0 :                         options->ip_qos_bulk = value2;
    1321                 :            :                 }
    1322                 :            :                 break;
    1323                 :            : 
    1324                 :            :         case oUseRoaming:
    1325                 :          0 :                 intptr = &options->use_roaming;
    1326                 :          0 :                 goto parse_flag;
    1327                 :            : 
    1328                 :            :         case oRequestTTY:
    1329                 :          0 :                 intptr = &options->request_tty;
    1330                 :          0 :                 multistate_ptr = multistate_requesttty;
    1331                 :          0 :                 goto parse_multistate;
    1332                 :            : 
    1333                 :            :         case oIgnoreUnknown:
    1334                 :          0 :                 charptr = &options->ignored_unknown;
    1335                 :          0 :                 goto parse_string;
    1336                 :            : 
    1337                 :            :         case oProxyUseFdpass:
    1338                 :          0 :                 intptr = &options->proxy_use_fdpass;
    1339                 :          0 :                 goto parse_flag;
    1340                 :            : 
    1341                 :            :         case oCanonicalDomains:
    1342                 :          0 :                 value = options->num_canonical_domains != 0;
    1343 [ #  # ][ #  # ]:          0 :                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    1344                 :          0 :                         valid_domain(arg, filename, linenum);
    1345 [ #  # ][ #  # ]:          0 :                         if (!*activep || value)
    1346                 :          0 :                                 continue;
    1347         [ #  # ]:          0 :                         if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
    1348                 :          0 :                                 fatal("%s line %d: too many hostname suffixes.",
    1349                 :            :                                     filename, linenum);
    1350                 :            :                         options->canonical_domains[
    1351                 :          0 :                             options->num_canonical_domains++] = xstrdup(arg);
    1352                 :            :                 }
    1353                 :            :                 break;
    1354                 :            : 
    1355                 :            :         case oCanonicalizePermittedCNAMEs:
    1356                 :          0 :                 value = options->num_permitted_cnames != 0;
    1357 [ #  # ][ #  # ]:          0 :                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    1358                 :            :                         /* Either '*' for everything or 'list:list' */
    1359 [ #  # ][ #  # ]:          0 :                         if (strcmp(arg, "*") == 0)
    1360                 :            :                                 arg2 = arg;
    1361                 :            :                         else {
    1362                 :          0 :                                 lowercase(arg);
    1363 [ #  # ][ #  # ]:          0 :                                 if ((arg2 = strchr(arg, ':')) == NULL ||
    1364                 :          0 :                                     arg2[1] == '\0') {
    1365                 :          0 :                                         fatal("%s line %d: "
    1366                 :            :                                             "Invalid permitted CNAME \"%s\"",
    1367                 :            :                                             filename, linenum, arg);
    1368                 :            :                                 }
    1369                 :          0 :                                 *arg2 = '\0';
    1370                 :          0 :                                 arg2++;
    1371                 :            :                         }
    1372 [ #  # ][ #  # ]:          0 :                         if (!*activep || value)
    1373                 :          0 :                                 continue;
    1374         [ #  # ]:          0 :                         if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
    1375                 :          0 :                                 fatal("%s line %d: too many permitted CNAMEs.",
    1376                 :            :                                     filename, linenum);
    1377                 :          0 :                         cname = options->permitted_cnames +
    1378                 :          0 :                             options->num_permitted_cnames++;
    1379                 :          0 :                         cname->source_list = xstrdup(arg);
    1380                 :          0 :                         cname->target_list = xstrdup(arg2);
    1381                 :            :                 }
    1382                 :            :                 break;
    1383                 :            : 
    1384                 :            :         case oCanonicalizeHostname:
    1385                 :          0 :                 intptr = &options->canonicalize_hostname;
    1386                 :          0 :                 multistate_ptr = multistate_canonicalizehostname;
    1387                 :          0 :                 goto parse_multistate;
    1388                 :            : 
    1389                 :            :         case oCanonicalizeMaxDots:
    1390                 :          0 :                 intptr = &options->canonicalize_max_dots;
    1391                 :          0 :                 goto parse_int;
    1392                 :            : 
    1393                 :            :         case oCanonicalizeFallbackLocal:
    1394                 :          0 :                 intptr = &options->canonicalize_fallback_local;
    1395                 :          0 :                 goto parse_flag;
    1396                 :            : 
    1397                 :            :         case oDeprecated:
    1398                 :          0 :                 debug("%s line %d: Deprecated option \"%s\"",
    1399                 :            :                     filename, linenum, keyword);
    1400                 :          0 :                 return 0;
    1401                 :            : 
    1402                 :            :         case oUnsupported:
    1403                 :          0 :                 error("%s line %d: Unsupported option \"%s\"",
    1404                 :            :                     filename, linenum, keyword);
    1405                 :          0 :                 return 0;
    1406                 :            : 
    1407                 :            :         default:
    1408                 :          0 :                 fatal("process_config_line: Unimplemented opcode %d", opcode);
    1409                 :            :         }
    1410                 :            : 
    1411                 :            :         /* Check that there is no garbage at end of line. */
    1412 [ -  + ][ #  # ]:      43253 :         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    1413                 :          0 :                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
    1414                 :            :                     filename, linenum, arg);
    1415                 :            :         }
    1416                 :            :         return 0;
    1417                 :            : }
    1418                 :            : 
    1419                 :            : 
    1420                 :            : /*
    1421                 :            :  * Reads the config file and modifies the options accordingly.  Options
    1422                 :            :  * should already be initialized before this call.  This never returns if
    1423                 :            :  * there is an error.  If the file does not exist, this returns 0.
    1424                 :            :  */
    1425                 :            : 
    1426                 :            : int
    1427                 :       2616 : read_config_file(const char *filename, struct passwd *pw, const char *host,
    1428                 :            :     Options *options, int flags)
    1429                 :            : {
    1430                 :            :         FILE *f;
    1431                 :            :         char line[1024];
    1432                 :            :         int active, linenum;
    1433                 :       2616 :         int bad_options = 0;
    1434                 :            : 
    1435         [ +  - ]:       2616 :         if ((f = fopen(filename, "r")) == NULL)
    1436                 :            :                 return 0;
    1437                 :            : 
    1438         [ -  + ]:       2616 :         if (flags & SSHCONF_CHECKPERM) {
    1439                 :            :                 struct stat sb;
    1440                 :            : 
    1441         [ #  # ]:          0 :                 if (fstat(fileno(f), &sb) == -1)
    1442                 :          0 :                         fatal("fstat %s: %s", filename, strerror(errno));
    1443 [ #  # ][ #  # ]:          0 :                 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
                 [ #  # ]
    1444                 :          0 :                     (sb.st_mode & 022) != 0))
    1445                 :          0 :                         fatal("Bad owner or permissions on %s", filename);
    1446                 :            :         }
    1447                 :            : 
    1448                 :       2616 :         debug("Reading configuration data %.200s", filename);
    1449                 :            : 
    1450                 :            :         /*
    1451                 :            :          * Mark that we are now processing the options.  This flag is turned
    1452                 :            :          * on/off by Host specifications.
    1453                 :            :          */
    1454                 :       2616 :         active = 1;
    1455                 :       2616 :         linenum = 0;
    1456         [ +  + ]:      57794 :         while (fgets(line, sizeof(line), f)) {
    1457                 :            :                 /* Update line number counter. */
    1458                 :      52562 :                 linenum++;
    1459         [ -  + ]:      52562 :                 if (process_config_line(options, pw, host, line, filename,
    1460                 :            :                     linenum, &active, flags & SSHCONF_USERCONF) != 0)
    1461                 :      52562 :                         bad_options++;
    1462                 :            :         }
    1463                 :       2616 :         fclose(f);
    1464         [ -  + ]:       2616 :         if (bad_options > 0)
    1465                 :          0 :                 fatal("%s: terminating, %d bad configuration options",
    1466                 :            :                     filename, bad_options);
    1467                 :            :         return 1;
    1468                 :            : }
    1469                 :            : 
    1470                 :            : /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
    1471                 :            : int
    1472                 :          0 : option_clear_or_none(const char *o)
    1473                 :            : {
    1474 [ +  + ][ +  - ]:       3924 :         return o == NULL || strcasecmp(o, "none") == 0;
         [ +  + ][ +  - ]
         [ +  + ][ +  - ]
         [ #  # ][ #  # ]
    1475                 :            : }
    1476                 :            : 
    1477                 :            : /*
    1478                 :            :  * Initializes options to special values that indicate that they have not yet
    1479                 :            :  * been set.  Read_config_file will only set options with this value. Options
    1480                 :            :  * are processed in the following order: command line, user config file,
    1481                 :            :  * system config file.  Last, fill_default_options is called.
    1482                 :            :  */
    1483                 :            : 
    1484                 :            : void
    1485                 :       1812 : initialize_options(Options * options)
    1486                 :            : {
    1487                 :            :         memset(options, 'X', sizeof(*options));
    1488                 :       1812 :         options->forward_agent = -1;
    1489                 :       1812 :         options->forward_x11 = -1;
    1490                 :       1812 :         options->forward_x11_trusted = -1;
    1491                 :       1812 :         options->forward_x11_timeout = -1;
    1492                 :       1812 :         options->exit_on_forward_failure = -1;
    1493                 :       1812 :         options->xauth_location = NULL;
    1494                 :       1812 :         options->gateway_ports = -1;
    1495                 :       1812 :         options->use_privileged_port = -1;
    1496                 :       1812 :         options->rsa_authentication = -1;
    1497                 :       1812 :         options->pubkey_authentication = -1;
    1498                 :       1812 :         options->challenge_response_authentication = -1;
    1499                 :       1812 :         options->gss_authentication = -1;
    1500                 :       1812 :         options->gss_deleg_creds = -1;
    1501                 :       1812 :         options->password_authentication = -1;
    1502                 :       1812 :         options->kbd_interactive_authentication = -1;
    1503                 :       1812 :         options->kbd_interactive_devices = NULL;
    1504                 :       1812 :         options->rhosts_rsa_authentication = -1;
    1505                 :       1812 :         options->hostbased_authentication = -1;
    1506                 :       1812 :         options->batch_mode = -1;
    1507                 :       1812 :         options->check_host_ip = -1;
    1508                 :       1812 :         options->strict_host_key_checking = -1;
    1509                 :       1812 :         options->compression = -1;
    1510                 :       1812 :         options->tcp_keep_alive = -1;
    1511                 :       1812 :         options->compression_level = -1;
    1512                 :       1812 :         options->port = -1;
    1513                 :       1812 :         options->address_family = -1;
    1514                 :       1812 :         options->connection_attempts = -1;
    1515                 :       1812 :         options->connection_timeout = -1;
    1516                 :       1812 :         options->number_of_password_prompts = -1;
    1517                 :       1812 :         options->cipher = -1;
    1518                 :       1812 :         options->ciphers = NULL;
    1519                 :       1812 :         options->macs = NULL;
    1520                 :       1812 :         options->kex_algorithms = NULL;
    1521                 :       1812 :         options->hostkeyalgorithms = NULL;
    1522                 :       1812 :         options->protocol = SSH_PROTO_UNKNOWN;
    1523                 :       1812 :         options->num_identity_files = 0;
    1524                 :       1812 :         options->hostname = NULL;
    1525                 :       1812 :         options->host_key_alias = NULL;
    1526                 :       1812 :         options->proxy_command = NULL;
    1527                 :       1812 :         options->user = NULL;
    1528                 :       1812 :         options->escape_char = -1;
    1529                 :       1812 :         options->num_system_hostfiles = 0;
    1530                 :       1812 :         options->num_user_hostfiles = 0;
    1531                 :       1812 :         options->local_forwards = NULL;
    1532                 :       1812 :         options->num_local_forwards = 0;
    1533                 :       1812 :         options->remote_forwards = NULL;
    1534                 :       1812 :         options->num_remote_forwards = 0;
    1535                 :       1812 :         options->clear_forwardings = -1;
    1536                 :       1812 :         options->log_level = SYSLOG_LEVEL_NOT_SET;
    1537                 :       1812 :         options->preferred_authentications = NULL;
    1538                 :       1812 :         options->bind_address = NULL;
    1539                 :       1812 :         options->pkcs11_provider = NULL;
    1540                 :       1812 :         options->enable_ssh_keysign = - 1;
    1541                 :       1812 :         options->no_host_authentication_for_localhost = - 1;
    1542                 :       1812 :         options->identities_only = - 1;
    1543                 :       1812 :         options->rekey_limit = - 1;
    1544                 :       1812 :         options->rekey_interval = -1;
    1545                 :       1812 :         options->verify_host_key_dns = -1;
    1546                 :       1812 :         options->server_alive_interval = -1;
    1547                 :       1812 :         options->server_alive_count_max = -1;
    1548                 :       1812 :         options->num_send_env = 0;
    1549                 :       1812 :         options->control_path = NULL;
    1550                 :       1812 :         options->control_master = -1;
    1551                 :       1812 :         options->control_persist = -1;
    1552                 :       1812 :         options->control_persist_timeout = 0;
    1553                 :       1812 :         options->hash_known_hosts = -1;
    1554                 :       1812 :         options->tun_open = -1;
    1555                 :       1812 :         options->tun_local = -1;
    1556                 :       1812 :         options->tun_remote = -1;
    1557                 :       1812 :         options->local_command = NULL;
    1558                 :       1812 :         options->permit_local_command = -1;
    1559                 :       1812 :         options->use_roaming = -1;
    1560                 :       1812 :         options->visual_host_key = -1;
    1561                 :       1812 :         options->ip_qos_interactive = -1;
    1562                 :       1812 :         options->ip_qos_bulk = -1;
    1563                 :       1812 :         options->request_tty = -1;
    1564                 :       1812 :         options->proxy_use_fdpass = -1;
    1565                 :       1812 :         options->ignored_unknown = NULL;
    1566                 :       1812 :         options->num_canonical_domains = 0;
    1567                 :       1812 :         options->num_permitted_cnames = 0;
    1568                 :       1812 :         options->canonicalize_max_dots = -1;
    1569                 :       1812 :         options->canonicalize_fallback_local = -1;
    1570                 :       1812 :         options->canonicalize_hostname = -1;
    1571                 :       1812 : }
    1572                 :            : 
    1573                 :            : /*
    1574                 :            :  * A petite version of fill_default_options() that just fills the options
    1575                 :            :  * needed for hostname canonicalization to proceed.
    1576                 :            :  */
    1577                 :            : void
    1578                 :       1308 : fill_default_options_for_canonicalization(Options *options)
    1579                 :            : {
    1580         [ +  - ]:       1308 :         if (options->canonicalize_max_dots == -1)
    1581                 :       1308 :                 options->canonicalize_max_dots = 1;
    1582         [ +  - ]:       1308 :         if (options->canonicalize_fallback_local == -1)
    1583                 :       1308 :                 options->canonicalize_fallback_local = 1;
    1584         [ +  - ]:       1308 :         if (options->canonicalize_hostname == -1)
    1585                 :       1308 :                 options->canonicalize_hostname = SSH_CANONICALISE_NO;
    1586                 :       1308 : }
    1587                 :            : 
    1588                 :            : /*
    1589                 :            :  * Called after processing other sources of option data, this fills those
    1590                 :            :  * options for which no value has been specified with their default values.
    1591                 :            :  */
    1592                 :            : void
    1593                 :       1308 : fill_default_options(Options * options)
    1594                 :            : {
    1595         [ +  + ]:       1308 :         if (options->forward_agent == -1)
    1596                 :       1302 :                 options->forward_agent = 0;
    1597         [ +  + ]:       1308 :         if (options->forward_x11 == -1)
    1598                 :       1306 :                 options->forward_x11 = 0;
    1599         [ +  - ]:       1308 :         if (options->forward_x11_trusted == -1)
    1600                 :       1308 :                 options->forward_x11_trusted = 0;
    1601         [ +  - ]:       1308 :         if (options->forward_x11_timeout == -1)
    1602                 :       1308 :                 options->forward_x11_timeout = 1200;
    1603         [ +  + ]:       1308 :         if (options->exit_on_forward_failure == -1)
    1604                 :       1219 :                 options->exit_on_forward_failure = 0;
    1605         [ +  - ]:       1308 :         if (options->xauth_location == NULL)
    1606                 :       1308 :                 options->xauth_location = _PATH_XAUTH;
    1607         [ +  - ]:       1308 :         if (options->gateway_ports == -1)
    1608                 :       1308 :                 options->gateway_ports = 0;
    1609         [ +  - ]:       1308 :         if (options->use_privileged_port == -1)
    1610                 :       1308 :                 options->use_privileged_port = 0;
    1611         [ -  + ]:       1308 :         if (options->rsa_authentication == -1)
    1612                 :          0 :                 options->rsa_authentication = 1;
    1613         [ -  + ]:       1308 :         if (options->pubkey_authentication == -1)
    1614                 :          0 :                 options->pubkey_authentication = 1;
    1615         [ -  + ]:       1308 :         if (options->challenge_response_authentication == -1)
    1616                 :          0 :                 options->challenge_response_authentication = 1;
    1617         [ +  - ]:       1308 :         if (options->gss_authentication == -1)
    1618                 :       1308 :                 options->gss_authentication = 0;
    1619         [ +  - ]:       1308 :         if (options->gss_deleg_creds == -1)
    1620                 :       1308 :                 options->gss_deleg_creds = 0;
    1621         [ -  + ]:       1308 :         if (options->password_authentication == -1)
    1622                 :          0 :                 options->password_authentication = 1;
    1623         [ +  - ]:       1308 :         if (options->kbd_interactive_authentication == -1)
    1624                 :       1308 :                 options->kbd_interactive_authentication = 1;
    1625         [ -  + ]:       1308 :         if (options->rhosts_rsa_authentication == -1)
    1626                 :          0 :                 options->rhosts_rsa_authentication = 0;
    1627         [ -  + ]:       1308 :         if (options->hostbased_authentication == -1)
    1628                 :          0 :                 options->hostbased_authentication = 0;
    1629         [ -  + ]:       1308 :         if (options->batch_mode == -1)
    1630                 :          0 :                 options->batch_mode = 0;
    1631         [ +  - ]:       1308 :         if (options->check_host_ip == -1)
    1632                 :       1308 :                 options->check_host_ip = 1;
    1633         [ -  + ]:       1308 :         if (options->strict_host_key_checking == -1)
    1634                 :          0 :                 options->strict_host_key_checking = 2;       /* 2 is default */
    1635         [ +  + ]:       1308 :         if (options->compression == -1)
    1636                 :       1227 :                 options->compression = 0;
    1637         [ +  - ]:       1308 :         if (options->tcp_keep_alive == -1)
    1638                 :       1308 :                 options->tcp_keep_alive = 1;
    1639         [ +  - ]:       1308 :         if (options->compression_level == -1)
    1640                 :       1308 :                 options->compression_level = 6;
    1641         [ -  + ]:       1308 :         if (options->port == -1)
    1642                 :          0 :                 options->port = 0;   /* Filled in ssh_connect. */
    1643         [ +  - ]:       1308 :         if (options->address_family == -1)
    1644                 :       1308 :                 options->address_family = AF_UNSPEC;
    1645         [ +  + ]:       1308 :         if (options->connection_attempts == -1)
    1646                 :       1276 :                 options->connection_attempts = 1;
    1647         [ +  - ]:       1308 :         if (options->number_of_password_prompts == -1)
    1648                 :       1308 :                 options->number_of_password_prompts = 3;
    1649                 :            :         /* Selected in ssh_login(). */
    1650         [ +  + ]:       1308 :         if (options->cipher == -1)
    1651                 :        838 :                 options->cipher = SSH_CIPHER_NOT_SET;
    1652                 :            :         /* options->ciphers, default set in myproposals.h */
    1653                 :            :         /* options->macs, default set in myproposals.h */
    1654                 :            :         /* options->kex_algorithms, default set in myproposals.h */
    1655                 :            :         /* options->hostkeyalgorithms, default set in myproposals.h */
    1656         [ -  + ]:       1308 :         if (options->protocol == SSH_PROTO_UNKNOWN)
    1657                 :          0 :                 options->protocol = SSH_PROTO_2;
    1658         [ -  + ]:       1308 :         if (options->num_identity_files == 0) {
    1659         [ #  # ]:          0 :                 if (options->protocol & SSH_PROTO_1) {
    1660                 :          0 :                         add_identity_file(options, "~/",
    1661                 :            :                             _PATH_SSH_CLIENT_IDENTITY, 0);
    1662                 :            :                 }
    1663         [ #  # ]:          0 :                 if (options->protocol & SSH_PROTO_2) {
    1664                 :          0 :                         add_identity_file(options, "~/",
    1665                 :            :                             _PATH_SSH_CLIENT_ID_RSA, 0);
    1666                 :          0 :                         add_identity_file(options, "~/",
    1667                 :            :                             _PATH_SSH_CLIENT_ID_DSA, 0);
    1668                 :            : #ifdef OPENSSL_HAS_ECC
    1669                 :          0 :                         add_identity_file(options, "~/",
    1670                 :            :                             _PATH_SSH_CLIENT_ID_ECDSA, 0);
    1671                 :            : #endif
    1672                 :          0 :                         add_identity_file(options, "~/",
    1673                 :            :                             _PATH_SSH_CLIENT_ID_ED25519, 0);
    1674                 :            :                 }
    1675                 :            :         }
    1676         [ +  - ]:       1308 :         if (options->escape_char == -1)
    1677                 :       1308 :                 options->escape_char = '~';
    1678         [ -  + ]:       1308 :         if (options->num_system_hostfiles == 0) {
    1679                 :          0 :                 options->system_hostfiles[options->num_system_hostfiles++] =
    1680                 :          0 :                     xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
    1681                 :          0 :                 options->system_hostfiles[options->num_system_hostfiles++] =
    1682                 :          0 :                     xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
    1683                 :            :         }
    1684         [ -  + ]:       1308 :         if (options->num_user_hostfiles == 0) {
    1685                 :          0 :                 options->user_hostfiles[options->num_user_hostfiles++] =
    1686                 :          0 :                     xstrdup(_PATH_SSH_USER_HOSTFILE);
    1687                 :          0 :                 options->user_hostfiles[options->num_user_hostfiles++] =
    1688                 :          0 :                     xstrdup(_PATH_SSH_USER_HOSTFILE2);
    1689                 :            :         }
    1690         [ -  + ]:       1308 :         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
    1691                 :          0 :                 options->log_level = SYSLOG_LEVEL_INFO;
    1692         [ +  + ]:       1308 :         if (options->clear_forwardings == 1)
    1693                 :          8 :                 clear_forwardings(options);
    1694         [ +  - ]:       1308 :         if (options->no_host_authentication_for_localhost == - 1)
    1695                 :       1308 :                 options->no_host_authentication_for_localhost = 0;
    1696         [ +  - ]:       1308 :         if (options->identities_only == -1)
    1697                 :       1308 :                 options->identities_only = 0;
    1698         [ +  - ]:       1308 :         if (options->enable_ssh_keysign == -1)
    1699                 :       1308 :                 options->enable_ssh_keysign = 0;
    1700         [ +  + ]:       1308 :         if (options->rekey_limit == -1)
    1701                 :       1229 :                 options->rekey_limit = 0;
    1702         [ +  + ]:       1308 :         if (options->rekey_interval == -1)
    1703                 :       1304 :                 options->rekey_interval = 0;
    1704         [ +  - ]:       1308 :         if (options->verify_host_key_dns == -1)
    1705                 :       1308 :                 options->verify_host_key_dns = 0;
    1706         [ +  + ]:       1308 :         if (options->server_alive_interval == -1)
    1707                 :       1090 :                 options->server_alive_interval = 0;
    1708         [ +  + ]:       1308 :         if (options->server_alive_count_max == -1)
    1709                 :       1090 :                 options->server_alive_count_max = 3;
    1710         [ +  + ]:       1308 :         if (options->control_master == -1)
    1711                 :       1306 :                 options->control_master = 0;
    1712         [ +  - ]:       1308 :         if (options->control_persist == -1) {
    1713                 :       1308 :                 options->control_persist = 0;
    1714                 :       1308 :                 options->control_persist_timeout = 0;
    1715                 :            :         }
    1716         [ +  - ]:       1308 :         if (options->hash_known_hosts == -1)
    1717                 :       1308 :                 options->hash_known_hosts = 0;
    1718         [ +  + ]:       1308 :         if (options->tun_open == -1)
    1719                 :       1300 :                 options->tun_open = SSH_TUNMODE_NO;
    1720         [ +  - ]:       1308 :         if (options->tun_local == -1)
    1721                 :       1308 :                 options->tun_local = SSH_TUNID_ANY;
    1722         [ +  - ]:       1308 :         if (options->tun_remote == -1)
    1723                 :       1308 :                 options->tun_remote = SSH_TUNID_ANY;
    1724         [ +  + ]:       1308 :         if (options->permit_local_command == -1)
    1725                 :       1302 :                 options->permit_local_command = 0;
    1726         [ +  - ]:       1308 :         if (options->use_roaming == -1)
    1727                 :       1308 :                 options->use_roaming = 1;
    1728         [ +  - ]:       1308 :         if (options->visual_host_key == -1)
    1729                 :       1308 :                 options->visual_host_key = 0;
    1730         [ +  - ]:       1308 :         if (options->ip_qos_interactive == -1)
    1731                 :       1308 :                 options->ip_qos_interactive = IPTOS_LOWDELAY;
    1732         [ +  - ]:       1308 :         if (options->ip_qos_bulk == -1)
    1733                 :       1308 :                 options->ip_qos_bulk = IPTOS_THROUGHPUT;
    1734         [ +  + ]:       1308 :         if (options->request_tty == -1)
    1735                 :       1306 :                 options->request_tty = REQUEST_TTY_AUTO;
    1736         [ +  - ]:       1308 :         if (options->proxy_use_fdpass == -1)
    1737                 :       1308 :                 options->proxy_use_fdpass = 0;
    1738         [ -  + ]:       1308 :         if (options->canonicalize_max_dots == -1)
    1739                 :          0 :                 options->canonicalize_max_dots = 1;
    1740         [ -  + ]:       1308 :         if (options->canonicalize_fallback_local == -1)
    1741                 :          0 :                 options->canonicalize_fallback_local = 1;
    1742         [ -  + ]:       1308 :         if (options->canonicalize_hostname == -1)
    1743                 :          0 :                 options->canonicalize_hostname = SSH_CANONICALISE_NO;
    1744                 :            : #define CLEAR_ON_NONE(v) \
    1745                 :            :         do { \
    1746                 :            :                 if (option_clear_or_none(v)) { \
    1747                 :            :                         free(v); \
    1748                 :            :                         v = NULL; \
    1749                 :            :                 } \
    1750                 :            :         } while(0)
    1751         [ +  + ]:       1308 :         CLEAR_ON_NONE(options->local_command);
    1752         [ +  + ]:       1308 :         CLEAR_ON_NONE(options->proxy_command);
    1753         [ +  + ]:       1308 :         CLEAR_ON_NONE(options->control_path);
    1754                 :            :         /* options->user will be set in the main program if appropriate */
    1755                 :            :         /* options->hostname will be set in the main program if appropriate */
    1756                 :            :         /* options->host_key_alias should not be set by default */
    1757                 :            :         /* options->preferred_authentications will be set in ssh */
    1758                 :       1308 : }
    1759                 :            : 
    1760                 :            : /*
    1761                 :            :  * parse_forward
    1762                 :            :  * parses a string containing a port forwarding specification of the form:
    1763                 :            :  *   dynamicfwd == 0
    1764                 :            :  *      [listenhost:]listenport:connecthost:connectport
    1765                 :            :  *   dynamicfwd == 1
    1766                 :            :  *      [listenhost:]listenport
    1767                 :            :  * returns number of arguments parsed or zero on error
    1768                 :            :  */
    1769                 :            : int
    1770                 :        155 : parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
    1771                 :            : {
    1772                 :            :         int i;
    1773                 :            :         char *p, *cp, *fwdarg[4];
    1774                 :            : 
    1775                 :            :         memset(fwd, '\0', sizeof(*fwd));
    1776                 :            : 
    1777                 :        155 :         cp = p = xstrdup(fwdspec);
    1778                 :            : 
    1779                 :            :         /* skip leading spaces */
    1780         [ -  + ]:        155 :         while (isspace((u_char)*cp))
    1781                 :          0 :                 cp++;
    1782                 :            : 
    1783         [ +  - ]:        618 :         for (i = 0; i < 4; ++i)
    1784         [ +  + ]:        618 :                 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
    1785                 :            :                         break;
    1786                 :            : 
    1787                 :            :         /* Check for trailing garbage */
    1788         [ -  + ]:        155 :         if (cp != NULL)
    1789                 :          0 :                 i = 0;  /* failure */
    1790                 :            : 
    1791   [ +  -  +  -  :        155 :         switch (i) {
                      - ]
    1792                 :            :         case 1:
    1793                 :          1 :                 fwd->listen_host = NULL;
    1794                 :          1 :                 fwd->listen_port = a2port(fwdarg[0]);
    1795                 :          1 :                 fwd->connect_host = xstrdup("socks");
    1796                 :          1 :                 break;
    1797                 :            : 
    1798                 :            :         case 2:
    1799                 :          0 :                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
    1800                 :          0 :                 fwd->listen_port = a2port(fwdarg[1]);
    1801                 :          0 :                 fwd->connect_host = xstrdup("socks");
    1802                 :          0 :                 break;
    1803                 :            : 
    1804                 :            :         case 3:
    1805                 :        154 :                 fwd->listen_host = NULL;
    1806                 :        154 :                 fwd->listen_port = a2port(fwdarg[0]);
    1807                 :        154 :                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
    1808                 :        154 :                 fwd->connect_port = a2port(fwdarg[2]);
    1809                 :        154 :                 break;
    1810                 :            : 
    1811                 :            :         case 4:
    1812                 :          0 :                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
    1813                 :          0 :                 fwd->listen_port = a2port(fwdarg[1]);
    1814                 :          0 :                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
    1815                 :          0 :                 fwd->connect_port = a2port(fwdarg[3]);
    1816                 :          0 :                 break;
    1817                 :            :         default:
    1818                 :            :                 i = 0; /* failure */
    1819                 :            :         }
    1820                 :            : 
    1821                 :        155 :         free(p);
    1822                 :            : 
    1823         [ +  + ]:        155 :         if (dynamicfwd) {
    1824         [ +  - ]:          1 :                 if (!(i == 1 || i == 2))
    1825                 :            :                         goto fail_free;
    1826                 :            :         } else {
    1827         [ +  - ]:        154 :                 if (!(i == 3 || i == 4))
    1828                 :            :                         goto fail_free;
    1829         [ +  - ]:        154 :                 if (fwd->connect_port <= 0)
    1830                 :            :                         goto fail_free;
    1831                 :            :         }
    1832                 :            : 
    1833 [ +  - ][ +  + ]:        155 :         if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
                 [ +  - ]
    1834                 :            :                 goto fail_free;
    1835                 :            : 
    1836 [ +  - ][ +  - ]:        155 :         if (fwd->connect_host != NULL &&
    1837                 :        155 :             strlen(fwd->connect_host) >= NI_MAXHOST)
    1838                 :            :                 goto fail_free;
    1839 [ -  + ][ #  # ]:        155 :         if (fwd->listen_host != NULL &&
    1840                 :          0 :             strlen(fwd->listen_host) >= NI_MAXHOST)
    1841                 :            :                 goto fail_free;
    1842                 :            : 
    1843                 :            : 
    1844                 :            :         return (i);
    1845                 :            : 
    1846                 :            :  fail_free:
    1847                 :          0 :         free(fwd->connect_host);
    1848                 :          0 :         fwd->connect_host = NULL;
    1849                 :          0 :         free(fwd->listen_host);
    1850                 :          0 :         fwd->listen_host = NULL;
    1851                 :          0 :         return (0);
    1852                 :            : }

Generated by: LCOV version 1.9