]> andersk Git - openssh.git/blobdiff - readconf.c
- dtucker@cvs.openbsd.org 2005/06/09 13:43:49
[openssh.git] / readconf.c
index c32a225ea6e9de205198c72bcb3a5d4969f587eb..5ec89e2f03d9af46b1732dfab97e68ae9afcf1e0 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.96 2002/06/08 05:17:01 markus Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.141 2005/06/08 11:25:09 djm Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -57,7 +57,6 @@ RCSID("$OpenBSD: readconf.c,v 1.96 2002/06/08 05:17:01 markus Exp $");
    Host fascist.blob.com
      Port 23123
      User tylonen
    Host fascist.blob.com
      Port 23123
      User tylonen
-     RhostsAuthentication no
      PasswordAuthentication no
 
    Host puukko.hut.fi
      PasswordAuthentication no
 
    Host puukko.hut.fi
@@ -75,12 +74,11 @@ RCSID("$OpenBSD: readconf.c,v 1.96 2002/06/08 05:17:01 markus Exp $");
    Host *
      ForwardAgent no
      ForwardX11 no
    Host *
      ForwardAgent no
      ForwardX11 no
-     RhostsAuthentication yes
      PasswordAuthentication yes
      RSAAuthentication yes
      RhostsRSAAuthentication yes
      StrictHostKeyChecking yes
      PasswordAuthentication yes
      RSAAuthentication yes
      RhostsRSAAuthentication yes
      StrictHostKeyChecking yes
-     KeepAlives no
+     TcpKeepAlive no
      IdentityFile ~/.ssh/identity
      Port 22
      EscapeChar ~
      IdentityFile ~/.ssh/identity
      Port 22
      EscapeChar ~
@@ -91,30 +89,25 @@ RCSID("$OpenBSD: readconf.c,v 1.96 2002/06/08 05:17:01 markus Exp $");
 
 typedef enum {
        oBadOption,
 
 typedef enum {
        oBadOption,
-       oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
-       oPasswordAuthentication, oRSAAuthentication, 
+       oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
+       oPasswordAuthentication, oRSAAuthentication,
        oChallengeResponseAuthentication, oXAuthLocation,
        oChallengeResponseAuthentication, oXAuthLocation,
-#if defined(KRB4) || defined(KRB5)
-       oKerberosAuthentication,
-#endif
-#if defined(AFS) || defined(KRB5)
-       oKerberosTgtPassing,
-#endif
-#ifdef AFS
-       oAFSTokenPassing,
-#endif
        oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
        oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
        oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
        oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
        oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
        oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
        oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
        oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
-       oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
+       oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
        oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
        oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
        oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
        oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
        oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
        oClearAllForwardings, oNoHostAuthenticationForLocalhost,
        oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
        oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
        oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
        oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
        oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
        oClearAllForwardings, oNoHostAuthenticationForLocalhost,
-       oDeprecated
+       oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
+       oAddressFamily, oGssAuthentication, oGssDelegateCreds,
+       oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
+       oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
+       oDeprecated, oUnsupported
 } OpCodes;
 
 /* Textual representations of the tokens. */
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -125,10 +118,11 @@ static struct {
 } keywords[] = {
        { "forwardagent", oForwardAgent },
        { "forwardx11", oForwardX11 },
 } keywords[] = {
        { "forwardagent", oForwardAgent },
        { "forwardx11", oForwardX11 },
+       { "forwardx11trusted", oForwardX11Trusted },
        { "xauthlocation", oXAuthLocation },
        { "gatewayports", oGatewayPorts },
        { "useprivilegedport", oUsePrivilegedPort },
        { "xauthlocation", oXAuthLocation },
        { "gatewayports", oGatewayPorts },
        { "useprivilegedport", oUsePrivilegedPort },
-       { "rhostsauthentication", oRhostsAuthentication },
+       { "rhostsauthentication", oDeprecated },
        { "passwordauthentication", oPasswordAuthentication },
        { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
        { "kbdinteractivedevices", oKbdInteractiveDevices },
        { "passwordauthentication", oPasswordAuthentication },
        { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
        { "kbdinteractivedevices", oKbdInteractiveDevices },
@@ -140,19 +134,21 @@ static struct {
        { "challengeresponseauthentication", oChallengeResponseAuthentication },
        { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
        { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
        { "challengeresponseauthentication", oChallengeResponseAuthentication },
        { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
        { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
-#if defined(KRB4) || defined(KRB5)
-       { "kerberosauthentication", oKerberosAuthentication },
-#endif
-#if defined(AFS) || defined(KRB5)
-       { "kerberostgtpassing", oKerberosTgtPassing },
-#endif
-#ifdef AFS
-       { "afstokenpassing", oAFSTokenPassing },
+       { "kerberosauthentication", oUnsupported },
+       { "kerberostgtpassing", oUnsupported },
+       { "afstokenpassing", oUnsupported },
+#if defined(GSSAPI)
+       { "gssapiauthentication", oGssAuthentication },
+       { "gssapidelegatecredentials", oGssDelegateCreds },
+#else
+       { "gssapiauthentication", oUnsupported },
+       { "gssapidelegatecredentials", oUnsupported },
 #endif
        { "fallbacktorsh", oDeprecated },
        { "usersh", oDeprecated },
        { "identityfile", oIdentityFile },
        { "identityfile2", oIdentityFile },                     /* alias */
 #endif
        { "fallbacktorsh", oDeprecated },
        { "usersh", oDeprecated },
        { "identityfile", oIdentityFile },
        { "identityfile2", oIdentityFile },                     /* alias */
+       { "identitiesonly", oIdentitiesOnly },
        { "hostname", oHostName },
        { "hostkeyalias", oHostKeyAlias },
        { "proxycommand", oProxyCommand },
        { "hostname", oHostName },
        { "hostkeyalias", oHostKeyAlias },
        { "proxycommand", oProxyCommand },
@@ -176,16 +172,32 @@ static struct {
        { "stricthostkeychecking", oStrictHostKeyChecking },
        { "compression", oCompression },
        { "compressionlevel", oCompressionLevel },
        { "stricthostkeychecking", oStrictHostKeyChecking },
        { "compression", oCompression },
        { "compressionlevel", oCompressionLevel },
-       { "keepalive", oKeepAlives },
+       { "tcpkeepalive", oTCPKeepAlive },
+       { "keepalive", oTCPKeepAlive },                         /* obsolete */
        { "numberofpasswordprompts", oNumberOfPasswordPrompts },
        { "loglevel", oLogLevel },
        { "dynamicforward", oDynamicForward },
        { "preferredauthentications", oPreferredAuthentications },
        { "hostkeyalgorithms", oHostKeyAlgorithms },
        { "bindaddress", oBindAddress },
        { "numberofpasswordprompts", oNumberOfPasswordPrompts },
        { "loglevel", oLogLevel },
        { "dynamicforward", oDynamicForward },
        { "preferredauthentications", oPreferredAuthentications },
        { "hostkeyalgorithms", oHostKeyAlgorithms },
        { "bindaddress", oBindAddress },
+#ifdef SMARTCARD
        { "smartcarddevice", oSmartcardDevice },
        { "smartcarddevice", oSmartcardDevice },
+#else
+       { "smartcarddevice", oUnsupported },
+#endif
        { "clearallforwardings", oClearAllForwardings },
        { "clearallforwardings", oClearAllForwardings },
+       { "enablesshkeysign", oEnableSSHKeysign },
+       { "verifyhostkeydns", oVerifyHostKeyDNS },
        { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
        { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+       { "rekeylimit", oRekeyLimit },
+       { "connecttimeout", oConnectTimeout },
+       { "addressfamily", oAddressFamily },
+       { "serveraliveinterval", oServerAliveInterval },
+       { "serveralivecountmax", oServerAliveCountMax },
+       { "sendenv", oSendEnv },
+       { "controlpath", oControlPath },
+       { "controlmaster", oControlMaster },
+       { "hashknownhosts", oHashKnownHosts },
        { NULL, oBadOption }
 };
 
        { NULL, oBadOption }
 };
 
@@ -195,21 +207,23 @@ static struct {
  */
 
 void
  */
 
 void
-add_local_forward(Options *options, u_short port, const char *host,
-                 u_short host_port)
+add_local_forward(Options *options, const Forward *newfwd)
 {
        Forward *fwd;
 {
        Forward *fwd;
-#ifndef HAVE_CYGWIN
+#ifndef NO_IPPORT_RESERVED_CONCEPT
        extern uid_t original_real_uid;
        extern uid_t original_real_uid;
-       if (port < IPPORT_RESERVED && original_real_uid != 0)
+       if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
                fatal("Privileged ports can only be forwarded by root.");
 #endif
        if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->local_forwards[options->num_local_forwards++];
                fatal("Privileged ports can only be forwarded by root.");
 #endif
        if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->local_forwards[options->num_local_forwards++];
-       fwd->port = port;
-       fwd->host = xstrdup(host);
-       fwd->host_port = host_port;
+
+       fwd->listen_host = (newfwd->listen_host == NULL) ?
+           NULL : xstrdup(newfwd->listen_host);
+       fwd->listen_port = newfwd->listen_port;
+       fwd->connect_host = xstrdup(newfwd->connect_host);
+       fwd->connect_port = newfwd->connect_port;
 }
 
 /*
 }
 
 /*
@@ -218,17 +232,19 @@ add_local_forward(Options *options, u_short port, const char *host,
  */
 
 void
  */
 
 void
-add_remote_forward(Options *options, u_short port, const char *host,
-                  u_short host_port)
+add_remote_forward(Options *options, const Forward *newfwd)
 {
        Forward *fwd;
        if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many remote forwards (max %d).",
                    SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->remote_forwards[options->num_remote_forwards++];
 {
        Forward *fwd;
        if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many remote forwards (max %d).",
                    SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->remote_forwards[options->num_remote_forwards++];
-       fwd->port = port;
-       fwd->host = xstrdup(host);
-       fwd->host_port = host_port;
+
+       fwd->listen_host = (newfwd->listen_host == NULL) ?
+           NULL : xstrdup(newfwd->listen_host);
+       fwd->listen_port = newfwd->listen_port;
+       fwd->connect_host = xstrdup(newfwd->connect_host);
+       fwd->connect_port = newfwd->connect_port;
 }
 
 static void
 }
 
 static void
@@ -236,11 +252,17 @@ clear_forwardings(Options *options)
 {
        int i;
 
 {
        int i;
 
-       for (i = 0; i < options->num_local_forwards; i++)
-               xfree(options->local_forwards[i].host);
+       for (i = 0; i < options->num_local_forwards; i++) {
+               if (options->local_forwards[i].listen_host != NULL)
+                       xfree(options->local_forwards[i].listen_host);
+               xfree(options->local_forwards[i].connect_host);
+       }
        options->num_local_forwards = 0;
        options->num_local_forwards = 0;
-       for (i = 0; i < options->num_remote_forwards; i++)
-               xfree(options->remote_forwards[i].host);
+       for (i = 0; i < options->num_remote_forwards; i++) {
+               if (options->remote_forwards[i].listen_host != NULL)
+                       xfree(options->remote_forwards[i].listen_host);
+               xfree(options->remote_forwards[i].connect_host);
+       }
        options->num_remote_forwards = 0;
 }
 
        options->num_remote_forwards = 0;
 }
 
@@ -266,16 +288,24 @@ parse_token(const char *cp, const char *filename, int linenum)
  * Processes a single option line as used in the configuration files. This
  * only sets those values that have not already been set.
  */
  * Processes a single option line as used in the configuration files. This
  * only sets those values that have not already been set.
  */
+#define WHITESPACE " \t\r\n"
 
 int
 process_config_line(Options *options, const char *host,
                    char *line, const char *filename, int linenum,
                    int *activep)
 {
 
 int
 process_config_line(Options *options, const char *host,
                    char *line, const char *filename, int linenum,
                    int *activep)
 {
-       char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
+       char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
        int opcode, *intptr, value;
        int opcode, *intptr, value;
-       u_short fwd_port, fwd_host_port;
-       char sfwd_host_port[6];
+       size_t len;
+       Forward fwd;
+
+       /* Strip trailing whitespace */
+       for (len = strlen(line) - 1; len > 0; len--) {
+               if (strchr(WHITESPACE, line[len]) == NULL)
+                       break;
+               line[len] = '\0';
+       }
 
        s = line;
        /* Get the keyword. (Each line is supposed to begin with a keyword). */
 
        s = line;
        /* Get the keyword. (Each line is supposed to begin with a keyword). */
@@ -293,6 +323,20 @@ process_config_line(Options *options, const char *host,
                /* don't panic, but count bad options */
                return -1;
                /* NOTREACHED */
                /* don't panic, but count bad options */
                return -1;
                /* NOTREACHED */
+       case oConnectTimeout:
+               intptr = &options->connection_timeout;
+parse_time:
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing time value.",
+                           filename, linenum);
+               if ((value = convtime(arg)) == -1)
+                       fatal("%s line %d: invalid time value.",
+                           filename, linenum);
+               if (*intptr == -1)
+                       *intptr = value;
+               break;
+
        case oForwardAgent:
                intptr = &options->forward_agent;
 parse_flag:
        case oForwardAgent:
                intptr = &options->forward_agent;
 parse_flag:
@@ -314,6 +358,10 @@ parse_flag:
                intptr = &options->forward_x11;
                goto parse_flag;
 
                intptr = &options->forward_x11;
                goto parse_flag;
 
+       case oForwardX11Trusted:
+               intptr = &options->forward_x11_trusted;
+               goto parse_flag;
+
        case oGatewayPorts:
                intptr = &options->gateway_ports;
                goto parse_flag;
        case oGatewayPorts:
                intptr = &options->gateway_ports;
                goto parse_flag;
@@ -322,10 +370,6 @@ parse_flag:
                intptr = &options->use_privileged_port;
                goto parse_flag;
 
                intptr = &options->use_privileged_port;
                goto parse_flag;
 
-       case oRhostsAuthentication:
-               intptr = &options->rhosts_authentication;
-               goto parse_flag;
-
        case oPasswordAuthentication:
                intptr = &options->password_authentication;
                goto parse_flag;
        case oPasswordAuthentication:
                intptr = &options->password_authentication;
                goto parse_flag;
@@ -357,21 +401,15 @@ parse_flag:
        case oChallengeResponseAuthentication:
                intptr = &options->challenge_response_authentication;
                goto parse_flag;
        case oChallengeResponseAuthentication:
                intptr = &options->challenge_response_authentication;
                goto parse_flag;
-#if defined(KRB4) || defined(KRB5)
-       case oKerberosAuthentication:
-               intptr = &options->kerberos_authentication;
-               goto parse_flag;
-#endif
-#if defined(AFS) || defined(KRB5)
-       case oKerberosTgtPassing:
-               intptr = &options->kerberos_tgt_passing;
+
+       case oGssAuthentication:
+               intptr = &options->gss_authentication;
                goto parse_flag;
                goto parse_flag;
-#endif
-#ifdef AFS
-       case oAFSTokenPassing:
-               intptr = &options->afs_token_passing;
+
+       case oGssDelegateCreds:
+               intptr = &options->gss_deleg_creds;
                goto parse_flag;
                goto parse_flag;
-#endif
+
        case oBatchMode:
                intptr = &options->batch_mode;
                goto parse_flag;
        case oBatchMode:
                intptr = &options->batch_mode;
                goto parse_flag;
@@ -380,8 +418,13 @@ parse_flag:
                intptr = &options->check_host_ip;
                goto parse_flag;
 
                intptr = &options->check_host_ip;
                goto parse_flag;
 
+       case oVerifyHostKeyDNS:
+               intptr = &options->verify_host_key_dns;
+               goto parse_yesnoask;
+
        case oStrictHostKeyChecking:
                intptr = &options->strict_host_key_checking;
        case oStrictHostKeyChecking:
                intptr = &options->strict_host_key_checking;
+parse_yesnoask:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing yes/no/ask argument.",
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing yes/no/ask argument.",
@@ -403,8 +446,8 @@ parse_flag:
                intptr = &options->compression;
                goto parse_flag;
 
                intptr = &options->compression;
                goto parse_flag;
 
-       case oKeepAlives:
-               intptr = &options->keepalives;
+       case oTCPKeepAlive:
+               intptr = &options->tcp_keep_alive;
                goto parse_flag;
 
        case oNoHostAuthenticationForLocalhost:
                goto parse_flag;
 
        case oNoHostAuthenticationForLocalhost:
@@ -419,6 +462,31 @@ parse_flag:
                intptr = &options->compression_level;
                goto parse_int;
 
                intptr = &options->compression_level;
                goto parse_int;
 
+       case oRekeyLimit:
+               intptr = &options->rekey_limit;
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
+               if (arg[0] < '0' || arg[0] > '9')
+                       fatal("%.200s line %d: Bad number.", filename, linenum);
+               value = strtol(arg, &endofnumber, 10);
+               if (arg == endofnumber)
+                       fatal("%.200s line %d: Bad number.", filename, linenum);
+               switch (toupper(*endofnumber)) {
+               case 'K':
+                       value *= 1<<10;
+                       break;
+               case 'M':
+                       value *= 1<<20;
+                       break;
+               case 'G':
+                       value *= 1<<30;
+                       break;
+               }
+               if (*activep && *intptr == -1)
+                       *intptr = value;
+               break;
+
        case oIdentityFile:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
        case oIdentityFile:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
@@ -485,17 +553,12 @@ parse_string:
                goto parse_string;
 
        case oProxyCommand:
                goto parse_string;
 
        case oProxyCommand:
+               if (s == NULL)
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
                charptr = &options->proxy_command;
                charptr = &options->proxy_command;
-               string = xstrdup("");
-               while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
-                       string = xrealloc(string, strlen(string) + strlen(arg) + 2);
-                       strcat(string, " ");
-                       strcat(string, arg);
-               }
+               len = strspn(s, WHITESPACE "=");
                if (*activep && *charptr == NULL)
                if (*activep && *charptr == NULL)
-                       *charptr = string;
-               else
-                       xfree(string);
+                       *charptr = xstrdup(s + len);
                return 0;
 
        case oPort:
                return 0;
 
        case oPort:
@@ -592,30 +655,26 @@ parse_int:
        case oLocalForward:
        case oRemoteForward:
                arg = strdelim(&s);
        case oLocalForward:
        case oRemoteForward:
                arg = strdelim(&s);
-               if (!arg || *arg == '\0')
+               if (arg == NULL || *arg == '\0')
                        fatal("%.200s line %d: Missing port argument.",
                            filename, linenum);
                        fatal("%.200s line %d: Missing port argument.",
                            filename, linenum);
-               if ((fwd_port = a2port(arg)) == 0)
-                       fatal("%.200s line %d: Bad listen port.",
-                           filename, linenum);
-               arg = strdelim(&s);
-               if (!arg || *arg == '\0')
-                       fatal("%.200s line %d: Missing second argument.",
+               arg2 = strdelim(&s);
+               if (arg2 == NULL || *arg2 == '\0')
+                       fatal("%.200s line %d: Missing target argument.",
                            filename, linenum);
                            filename, linenum);
-               if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
-                   sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
+
+               /* construct a string for parse_forward */
+               snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
+
+               if (parse_forward(&fwd, fwdarg) == 0)
                        fatal("%.200s line %d: Bad forwarding specification.",
                            filename, linenum);
                        fatal("%.200s line %d: Bad forwarding specification.",
                            filename, linenum);
-               if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
-                       fatal("%.200s line %d: Bad forwarding port.",
-                           filename, linenum);
+
                if (*activep) {
                        if (opcode == oLocalForward)
                if (*activep) {
                        if (opcode == oLocalForward)
-                               add_local_forward(options, fwd_port, buf,
-                                   fwd_host_port);
+                               add_local_forward(options, &fwd);
                        else if (opcode == oRemoteForward)
                        else if (opcode == oRemoteForward)
-                               add_remote_forward(options, fwd_port, buf,
-                                   fwd_host_port);
+                               add_remote_forward(options, &fwd);
                }
                break;
 
                }
                break;
 
@@ -624,12 +683,25 @@ parse_int:
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing port argument.",
                            filename, linenum);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing port argument.",
                            filename, linenum);
-               fwd_port = a2port(arg);
-               if (fwd_port == 0)
+               memset(&fwd, '\0', sizeof(fwd));
+               fwd.connect_host = "socks";
+               fwd.listen_host = hpdelim(&arg);
+               if (fwd.listen_host == NULL ||
+                   strlen(fwd.listen_host) >= NI_MAXHOST)
+                       fatal("%.200s line %d: Bad forwarding specification.",
+                           filename, linenum);
+               if (arg) {
+                       fwd.listen_port = a2port(arg);
+                       fwd.listen_host = cleanhostname(fwd.listen_host);
+               } else {
+                       fwd.listen_port = a2port(fwd.listen_host);
+                       fwd.listen_host = "";
+               }
+               if (fwd.listen_port == 0)
                        fatal("%.200s line %d: Badly formatted port number.",
                            filename, linenum);
                if (*activep)
                        fatal("%.200s line %d: Badly formatted port number.",
                            filename, linenum);
                if (*activep)
-                       add_local_forward(options, fwd_port, "socks4", 0);
+                       add_local_forward(options, &fwd);
                break;
 
        case oClearAllForwardings:
                break;
 
        case oClearAllForwardings:
@@ -669,10 +741,96 @@ parse_int:
                        *intptr = value;
                break;
 
                        *intptr = value;
                break;
 
+       case oAddressFamily:
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing address family.",
+                           filename, linenum);
+               intptr = &options->address_family;
+               if (strcasecmp(arg, "inet") == 0)
+                       value = AF_INET;
+               else if (strcasecmp(arg, "inet6") == 0)
+                       value = AF_INET6;
+               else if (strcasecmp(arg, "any") == 0)
+                       value = AF_UNSPEC;
+               else
+                       fatal("Unsupported AddressFamily \"%s\"", arg);
+               if (*activep && *intptr == -1)
+                       *intptr = value;
+               break;
+
+       case oEnableSSHKeysign:
+               intptr = &options->enable_ssh_keysign;
+               goto parse_flag;
+
+       case oIdentitiesOnly:
+               intptr = &options->identities_only;
+               goto parse_flag;
+
+       case oServerAliveInterval:
+               intptr = &options->server_alive_interval;
+               goto parse_time;
+
+       case oServerAliveCountMax:
+               intptr = &options->server_alive_count_max;
+               goto parse_int;
+
+       case oSendEnv:
+               while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+                       if (strchr(arg, '=') != NULL)
+                               fatal("%s line %d: Invalid environment name.",
+                                   filename, linenum);
+                       if (!*activep)
+                               continue;
+                       if (options->num_send_env >= MAX_SEND_ENV)
+                               fatal("%s line %d: too many send env.",
+                                   filename, linenum);
+                       options->send_env[options->num_send_env++] =
+                           xstrdup(arg);
+               }
+               break;
+
+       case oControlPath:
+               charptr = &options->control_path;
+               goto parse_string;
+
+       case oControlMaster:
+               intptr = &options->control_master;
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%.200s line %d: Missing ControlMaster argument.",
+                           filename, linenum);
+               value = 0;      /* To avoid compiler warning... */
+               if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
+                       value = SSHCTL_MASTER_YES;
+               else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
+                       value = SSHCTL_MASTER_NO;
+               else if (strcmp(arg, "auto") == 0)
+                       value = SSHCTL_MASTER_AUTO;
+               else if (strcmp(arg, "ask") == 0)
+                       value = SSHCTL_MASTER_ASK;
+               else if (strcmp(arg, "autoask") == 0)
+                       value = SSHCTL_MASTER_AUTO_ASK;
+               else
+                       fatal("%.200s line %d: Bad ControlMaster argument.",
+                           filename, linenum);
+               if (*activep && *intptr == -1)
+                       *intptr = value;
+               break;
+
+       case oHashKnownHosts:
+               intptr = &options->hash_known_hosts;
+               goto parse_flag;
+
        case oDeprecated:
        case oDeprecated:
-               fatal("%s line %d: Deprecated option \"%s\"",
+               debug("%s line %d: Deprecated option \"%s\"",
                    filename, linenum, keyword);
                    filename, linenum, keyword);
-               break;
+               return 0;
+
+       case oUnsupported:
+               error("%s line %d: Unsupported option \"%s\"",
+                   filename, linenum, keyword);
+               return 0;
 
        default:
                fatal("process_config_line: Unimplemented opcode %d", opcode);
 
        default:
                fatal("process_config_line: Unimplemented opcode %d", opcode);
@@ -694,7 +852,8 @@ parse_int:
  */
 
 int
  */
 
 int
-read_config_file(const char *filename, const char *host, Options *options)
+read_config_file(const char *filename, const char *host, Options *options,
+    int checkperm)
 {
        FILE *f;
        char line[1024];
 {
        FILE *f;
        char line[1024];
@@ -702,10 +861,19 @@ read_config_file(const char *filename, const char *host, Options *options)
        int bad_options = 0;
 
        /* Open the file. */
        int bad_options = 0;
 
        /* Open the file. */
-       f = fopen(filename, "r");
-       if (!f)
+       if ((f = fopen(filename, "r")) == NULL)
                return 0;
 
                return 0;
 
+       if (checkperm) {
+               struct stat sb;
+
+               if (fstat(fileno(f), &sb) == -1)
+                       fatal("fstat %s: %s", filename, strerror(errno));
+               if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
+                   (sb.st_mode & 022) != 0))
+                       fatal("Bad owner or permissions on %s", filename);
+       }
+
        debug("Reading configuration data %.200s", filename);
 
        /*
        debug("Reading configuration data %.200s", filename);
 
        /*
@@ -740,22 +908,15 @@ initialize_options(Options * options)
        memset(options, 'X', sizeof(*options));
        options->forward_agent = -1;
        options->forward_x11 = -1;
        memset(options, 'X', sizeof(*options));
        options->forward_agent = -1;
        options->forward_x11 = -1;
+       options->forward_x11_trusted = -1;
        options->xauth_location = NULL;
        options->gateway_ports = -1;
        options->use_privileged_port = -1;
        options->xauth_location = NULL;
        options->gateway_ports = -1;
        options->use_privileged_port = -1;
-       options->rhosts_authentication = -1;
        options->rsa_authentication = -1;
        options->pubkey_authentication = -1;
        options->challenge_response_authentication = -1;
        options->rsa_authentication = -1;
        options->pubkey_authentication = -1;
        options->challenge_response_authentication = -1;
-#if defined(KRB4) || defined(KRB5)
-       options->kerberos_authentication = -1;
-#endif
-#if defined(AFS) || defined(KRB5)
-       options->kerberos_tgt_passing = -1;
-#endif
-#ifdef AFS
-       options->afs_token_passing = -1;
-#endif
+       options->gss_authentication = -1;
+       options->gss_deleg_creds = -1;
        options->password_authentication = -1;
        options->kbd_interactive_authentication = -1;
        options->kbd_interactive_devices = NULL;
        options->password_authentication = -1;
        options->kbd_interactive_authentication = -1;
        options->kbd_interactive_devices = NULL;
@@ -765,10 +926,12 @@ initialize_options(Options * options)
        options->check_host_ip = -1;
        options->strict_host_key_checking = -1;
        options->compression = -1;
        options->check_host_ip = -1;
        options->strict_host_key_checking = -1;
        options->compression = -1;
-       options->keepalives = -1;
+       options->tcp_keep_alive = -1;
        options->compression_level = -1;
        options->port = -1;
        options->compression_level = -1;
        options->port = -1;
+       options->address_family = -1;
        options->connection_attempts = -1;
        options->connection_attempts = -1;
+       options->connection_timeout = -1;
        options->number_of_password_prompts = -1;
        options->cipher = -1;
        options->ciphers = NULL;
        options->number_of_password_prompts = -1;
        options->cipher = -1;
        options->ciphers = NULL;
@@ -792,7 +955,17 @@ initialize_options(Options * options)
        options->preferred_authentications = NULL;
        options->bind_address = NULL;
        options->smartcard_device = NULL;
        options->preferred_authentications = NULL;
        options->bind_address = NULL;
        options->smartcard_device = NULL;
+       options->enable_ssh_keysign = - 1;
        options->no_host_authentication_for_localhost = - 1;
        options->no_host_authentication_for_localhost = - 1;
+       options->identities_only = - 1;
+       options->rekey_limit = - 1;
+       options->verify_host_key_dns = -1;
+       options->server_alive_interval = -1;
+       options->server_alive_count_max = -1;
+       options->num_send_env = 0;
+       options->control_path = NULL;
+       options->control_master = -1;
+       options->hash_known_hosts = -1;
 }
 
 /*
 }
 
 /*
@@ -809,38 +982,30 @@ fill_default_options(Options * options)
                options->forward_agent = 0;
        if (options->forward_x11 == -1)
                options->forward_x11 = 0;
                options->forward_agent = 0;
        if (options->forward_x11 == -1)
                options->forward_x11 = 0;
+       if (options->forward_x11_trusted == -1)
+               options->forward_x11_trusted = 0;
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
        if (options->gateway_ports == -1)
                options->gateway_ports = 0;
        if (options->use_privileged_port == -1)
                options->use_privileged_port = 0;
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
        if (options->gateway_ports == -1)
                options->gateway_ports = 0;
        if (options->use_privileged_port == -1)
                options->use_privileged_port = 0;
-       if (options->rhosts_authentication == -1)
-               options->rhosts_authentication = 1;
        if (options->rsa_authentication == -1)
                options->rsa_authentication = 1;
        if (options->pubkey_authentication == -1)
                options->pubkey_authentication = 1;
        if (options->challenge_response_authentication == -1)
                options->challenge_response_authentication = 1;
        if (options->rsa_authentication == -1)
                options->rsa_authentication = 1;
        if (options->pubkey_authentication == -1)
                options->pubkey_authentication = 1;
        if (options->challenge_response_authentication == -1)
                options->challenge_response_authentication = 1;
-#if defined(KRB4) || defined(KRB5)
-       if (options->kerberos_authentication == -1)
-               options->kerberos_authentication = 1;
-#endif
-#if defined(AFS) || defined(KRB5)
-       if (options->kerberos_tgt_passing == -1)
-               options->kerberos_tgt_passing = 1;
-#endif
-#ifdef AFS
-       if (options->afs_token_passing == -1)
-               options->afs_token_passing = 1;
-#endif
+       if (options->gss_authentication == -1)
+               options->gss_authentication = 0;
+       if (options->gss_deleg_creds == -1)
+               options->gss_deleg_creds = 0;
        if (options->password_authentication == -1)
                options->password_authentication = 1;
        if (options->kbd_interactive_authentication == -1)
                options->kbd_interactive_authentication = 1;
        if (options->rhosts_rsa_authentication == -1)
        if (options->password_authentication == -1)
                options->password_authentication = 1;
        if (options->kbd_interactive_authentication == -1)
                options->kbd_interactive_authentication = 1;
        if (options->rhosts_rsa_authentication == -1)
-               options->rhosts_rsa_authentication = 1;
+               options->rhosts_rsa_authentication = 0;
        if (options->hostbased_authentication == -1)
                options->hostbased_authentication = 0;
        if (options->batch_mode == -1)
        if (options->hostbased_authentication == -1)
                options->hostbased_authentication = 0;
        if (options->batch_mode == -1)
@@ -851,12 +1016,14 @@ fill_default_options(Options * options)
                options->strict_host_key_checking = 2;  /* 2 is default */
        if (options->compression == -1)
                options->compression = 0;
                options->strict_host_key_checking = 2;  /* 2 is default */
        if (options->compression == -1)
                options->compression = 0;
-       if (options->keepalives == -1)
-               options->keepalives = 1;
+       if (options->tcp_keep_alive == -1)
+               options->tcp_keep_alive = 1;
        if (options->compression_level == -1)
                options->compression_level = 6;
        if (options->port == -1)
                options->port = 0;      /* Filled in ssh_connect. */
        if (options->compression_level == -1)
                options->compression_level = 6;
        if (options->port == -1)
                options->port = 0;      /* Filled in ssh_connect. */
+       if (options->address_family == -1)
+               options->address_family = AF_UNSPEC;
        if (options->connection_attempts == -1)
                options->connection_attempts = 1;
        if (options->number_of_password_prompts == -1)
        if (options->connection_attempts == -1)
                options->connection_attempts = 1;
        if (options->number_of_password_prompts == -1)
@@ -907,9 +1074,90 @@ fill_default_options(Options * options)
                clear_forwardings(options);
        if (options->no_host_authentication_for_localhost == - 1)
                options->no_host_authentication_for_localhost = 0;
                clear_forwardings(options);
        if (options->no_host_authentication_for_localhost == - 1)
                options->no_host_authentication_for_localhost = 0;
+       if (options->identities_only == -1)
+               options->identities_only = 0;
+       if (options->enable_ssh_keysign == -1)
+               options->enable_ssh_keysign = 0;
+       if (options->rekey_limit == -1)
+               options->rekey_limit = 0;
+       if (options->verify_host_key_dns == -1)
+               options->verify_host_key_dns = 0;
+       if (options->server_alive_interval == -1)
+               options->server_alive_interval = 0;
+       if (options->server_alive_count_max == -1)
+               options->server_alive_count_max = 3;
+       if (options->control_master == -1)
+               options->control_master = 0;
+       if (options->hash_known_hosts == -1)
+               options->hash_known_hosts = 0;
        /* options->proxy_command should not be set by default */
        /* options->user will be set in the main program if appropriate */
        /* options->hostname will be set in the main program if appropriate */
        /* options->host_key_alias should not be set by default */
        /* options->preferred_authentications will be set in ssh */
 }
        /* options->proxy_command should not be set by default */
        /* options->user will be set in the main program if appropriate */
        /* options->hostname will be set in the main program if appropriate */
        /* options->host_key_alias should not be set by default */
        /* options->preferred_authentications will be set in ssh */
 }
+
+/*
+ * parse_forward
+ * parses a string containing a port forwarding specification of the form:
+ *     [listenhost:]listenport:connecthost:connectport
+ * returns number of arguments parsed or zero on error
+ */
+int
+parse_forward(Forward *fwd, const char *fwdspec)
+{
+       int i;
+       char *p, *cp, *fwdarg[4];
+
+       memset(fwd, '\0', sizeof(*fwd));
+
+       cp = p = xstrdup(fwdspec);
+
+       /* skip leading spaces */
+       while (*cp && isspace(*cp))
+               cp++;
+
+       for (i = 0; i < 4; ++i)
+               if ((fwdarg[i] = hpdelim(&cp)) == NULL)
+                       break;
+
+       /* Check for trailing garbage in 4-arg case*/
+       if (cp != NULL)
+               i = 0;  /* failure */
+
+       switch (i) {
+       case 3:
+               fwd->listen_host = NULL;
+               fwd->listen_port = a2port(fwdarg[0]);
+               fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
+               fwd->connect_port = a2port(fwdarg[2]);
+               break;
+
+       case 4:
+               fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
+               fwd->listen_port = a2port(fwdarg[1]);
+               fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
+               fwd->connect_port = a2port(fwdarg[3]);
+               break;
+       default:
+               i = 0; /* failure */
+       }
+
+       xfree(p);
+
+       if (fwd->listen_port == 0 && fwd->connect_port == 0)
+               goto fail_free;
+
+       if (fwd->connect_host != NULL &&
+           strlen(fwd->connect_host) >= NI_MAXHOST)
+               goto fail_free;
+
+       return (i);
+
+ fail_free:
+       if (fwd->connect_host != NULL)
+               xfree(fwd->connect_host);
+       if (fwd->listen_host != NULL)
+               xfree(fwd->listen_host);
+       return (0);
+}
This page took 0.065006 seconds and 4 git commands to generate.