]> andersk Git - openssh.git/blobdiff - readconf.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / readconf.c
index 83069d3ad0001de02664df20770178ce37290461..d424c16974477eeca622230dbe6edcf05feea5eb 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: readconf.c,v 1.182 2010/01/09 23:04:13 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.90 2001/09/19 19:24:18 stevesk Exp $");
 
 
-#include "ssh.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
 #include "xmalloc.h"
 #include "xmalloc.h"
+#include "ssh.h"
 #include "compat.h"
 #include "cipher.h"
 #include "pathnames.h"
 #include "log.h"
 #include "compat.h"
 #include "cipher.h"
 #include "pathnames.h"
 #include "log.h"
+#include "key.h"
 #include "readconf.h"
 #include "match.h"
 #include "misc.h"
 #include "readconf.h"
 #include "match.h"
 #include "misc.h"
+#include "buffer.h"
 #include "kex.h"
 #include "mac.h"
 
 #include "kex.h"
 #include "mac.h"
 
@@ -41,7 +58,7 @@ RCSID("$OpenBSD: readconf.c,v 1.90 2001/09/19 19:24:18 stevesk Exp $");
    # that they are given in.
 
    Host *.ngs.fi ngs.fi
    # that they are given in.
 
    Host *.ngs.fi ngs.fi
-     FallBackToRsh no
+     User foo
 
    Host fake.com
      HostName another.host.name.real.org
 
    Host fake.com
      HostName another.host.name.real.org
@@ -57,7 +74,6 @@ RCSID("$OpenBSD: readconf.c,v 1.90 2001/09/19 19:24:18 stevesk 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
@@ -65,24 +81,25 @@ RCSID("$OpenBSD: readconf.c,v 1.90 2001/09/19 19:24:18 stevesk Exp $");
      ProxyCommand ssh-proxy %h %p
 
    Host *.fr
      ProxyCommand ssh-proxy %h %p
 
    Host *.fr
-     UseRsh yes
+     PublicKeyAuthentication no
 
    Host *.su
      Cipher none
      PasswordAuthentication no
 
 
    Host *.su
      Cipher none
      PasswordAuthentication no
 
+   Host vpn.fake.com
+     Tunnel yes
+     TunnelDevice 3
+
    # Defaults for various options
    Host *
      ForwardAgent no
      ForwardX11 no
    # Defaults for various options
    Host *
      ForwardAgent no
      ForwardX11 no
-     RhostsAuthentication yes
      PasswordAuthentication yes
      RSAAuthentication yes
      RhostsRSAAuthentication yes
      PasswordAuthentication yes
      RSAAuthentication yes
      RhostsRSAAuthentication yes
-     FallBackToRsh no
-     UseRsh no
      StrictHostKeyChecking yes
      StrictHostKeyChecking yes
-     KeepAlives no
+     TcpKeepAlive no
      IdentityFile ~/.ssh/identity
      Port 22
      EscapeChar ~
      IdentityFile ~/.ssh/identity
      Port 22
      EscapeChar ~
@@ -93,29 +110,28 @@ RCSID("$OpenBSD: readconf.c,v 1.90 2001/09/19 19:24:18 stevesk Exp $");
 
 typedef enum {
        oBadOption,
 
 typedef enum {
        oBadOption,
-       oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
-       oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
+       oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
+       oExitOnForwardFailure,
+       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,
        oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
        oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
        oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
        oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
        oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
-       oClearAllForwardings
+       oClearAllForwardings, oNoHostAuthenticationForLocalhost,
+       oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
+       oAddressFamily, oGssAuthentication, oGssDelegateCreds,
+       oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
+       oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
+       oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
+       oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
+       oDeprecated, oUnsupported
 } OpCodes;
 
 /* Textual representations of the tokens. */
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -126,10 +142,12 @@ static struct {
 } keywords[] = {
        { "forwardagent", oForwardAgent },
        { "forwardx11", oForwardX11 },
 } keywords[] = {
        { "forwardagent", oForwardAgent },
        { "forwardx11", oForwardX11 },
+       { "forwardx11trusted", oForwardX11Trusted },
+       { "exitonforwardfailure", oExitOnForwardFailure },
        { "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 },
@@ -141,19 +159,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 },
+       { "kerberosauthentication", oUnsupported },
+       { "kerberostgtpassing", oUnsupported },
+       { "afstokenpassing", oUnsupported },
+#if defined(GSSAPI)
+       { "gssapiauthentication", oGssAuthentication },
+       { "gssapidelegatecredentials", oGssDelegateCreds },
+#else
+       { "gssapiauthentication", oUnsupported },
+       { "gssapidelegatecredentials", oUnsupported },
 #endif
 #endif
-#if defined(AFS) || defined(KRB5)
-       { "kerberostgtpassing", oKerberosTgtPassing },
-#endif
-#ifdef AFS
-       { "afstokenpassing", oAFSTokenPassing },
-#endif
-       { "fallbacktorsh", oFallBackToRsh },
-       { "usersh", oUseRsh },
+       { "fallbacktorsh", oDeprecated },
+       { "usersh", oDeprecated },
        { "identityfile", oIdentityFile },
        { "identityfile", oIdentityFile },
-       { "identityfile2", oIdentityFile },                     /* alias */
+       { "identityfile2", oIdentityFile },                     /* obsolete */
+       { "identitiesonly", oIdentitiesOnly },
        { "hostname", oHostName },
        { "hostkeyalias", oHostKeyAlias },
        { "proxycommand", oProxyCommand },
        { "hostname", oHostName },
        { "hostkeyalias", oHostKeyAlias },
        { "proxycommand", oProxyCommand },
@@ -168,8 +188,8 @@ static struct {
        { "host", oHost },
        { "escapechar", oEscapeChar },
        { "globalknownhostsfile", oGlobalKnownHostsFile },
        { "host", oHost },
        { "escapechar", oEscapeChar },
        { "globalknownhostsfile", oGlobalKnownHostsFile },
-       { "userknownhostsfile", oUserKnownHostsFile },          /* obsolete */
-       { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
+       { "globalknownhostsfile2", oGlobalKnownHostsFile2 },    /* obsolete */
+       { "userknownhostsfile", oUserKnownHostsFile },
        { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
        { "connectionattempts", oConnectionAttempts },
        { "batchmode", oBatchMode },
        { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
        { "connectionattempts", oConnectionAttempts },
        { "batchmode", oBatchMode },
@@ -177,16 +197,46 @@ 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 },
-       { "clearallforwardings", oClearAllForwardings }, 
-       { NULL, 0 }
+#else
+       { "smartcarddevice", oUnsupported },
+#endif
+       { "clearallforwardings", oClearAllForwardings },
+       { "enablesshkeysign", oEnableSSHKeysign },
+       { "verifyhostkeydns", oVerifyHostKeyDNS },
+       { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+       { "rekeylimit", oRekeyLimit },
+       { "connecttimeout", oConnectTimeout },
+       { "addressfamily", oAddressFamily },
+       { "serveraliveinterval", oServerAliveInterval },
+       { "serveralivecountmax", oServerAliveCountMax },
+       { "sendenv", oSendEnv },
+       { "controlpath", oControlPath },
+       { "controlmaster", oControlMaster },
+       { "hashknownhosts", oHashKnownHosts },
+       { "tunnel", oTunnel },
+       { "tunneldevice", oTunnelDevice },
+       { "localcommand", oLocalCommand },
+       { "permitlocalcommand", oPermitLocalCommand },
+       { "visualhostkey", oVisualHostKey },
+       { "useroaming", oUseRoaming },
+#ifdef JPAKE
+       { "zeroknowledgepasswordauthentication",
+           oZeroKnowledgePasswordAuthentication },
+#else
+       { "zeroknowledgepasswordauthentication", oUnsupported },
+#endif
+
+       { NULL, oBadOption }
 };
 
 /*
 };
 
 /*
@@ -195,21 +245,22 @@ 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;
+       fwd->listen_port = newfwd->listen_port;
+       fwd->connect_host = newfwd->connect_host;
+       fwd->connect_port = newfwd->connect_port;
 }
 
 /*
 }
 
 /*
@@ -218,17 +269,18 @@ 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).",
 {
        Forward *fwd;
        if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many remote forwards (max %d).",
-                     SSH_MAX_FORWARDS_PER_DIRECTION);
+                   SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->remote_forwards[options->num_remote_forwards++];
        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;
+       fwd->listen_port = newfwd->listen_port;
+       fwd->connect_host = newfwd->connect_host;
+       fwd->connect_port = newfwd->connect_port;
 }
 
 static void
 }
 
 static void
@@ -236,12 +288,19 @@ 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;
+       options->tun_open = SSH_TUNMODE_NO;
 }
 
 /*
 }
 
 /*
@@ -266,20 +325,31 @@ 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;
-       int opcode, *intptr, value;
-       u_short fwd_port, fwd_host_port;
-       char sfwd_host_port[6];
+       char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
+       int opcode, *intptr, value, value2, scale;
+       LogLevel *log_level_ptr;
+       long long orig, val64;
+       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). */
-       keyword = strdelim(&s);
+       if ((keyword = strdelim(&s)) == NULL)
+               return 0;
        /* Ignore leading whitespace. */
        if (*keyword == '\0')
                keyword = strdelim(&s);
        /* Ignore leading whitespace. */
        if (*keyword == '\0')
                keyword = strdelim(&s);
@@ -293,6 +363,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 (*activep && *intptr == -1)
+                       *intptr = value;
+               break;
+
        case oForwardAgent:
                intptr = &options->forward_agent;
 parse_flag:
        case oForwardAgent:
                intptr = &options->forward_agent;
 parse_flag:
@@ -314,22 +398,30 @@ 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;
 
-       case oUsePrivilegedPort:
-               intptr = &options->use_privileged_port;
+       case oExitOnForwardFailure:
+               intptr = &options->exit_on_forward_failure;
                goto parse_flag;
 
                goto parse_flag;
 
-       case oRhostsAuthentication:
-               intptr = &options->rhosts_authentication;
+       case oUsePrivilegedPort:
+               intptr = &options->use_privileged_port;
                goto parse_flag;
 
        case oPasswordAuthentication:
                intptr = &options->password_authentication;
                goto parse_flag;
 
                goto parse_flag;
 
        case oPasswordAuthentication:
                intptr = &options->password_authentication;
                goto parse_flag;
 
+       case oZeroKnowledgePasswordAuthentication:
+               intptr = &options->zero_knowledge_password_authentication;
+               goto parse_flag;
+
        case oKbdInteractiveAuthentication:
                intptr = &options->kbd_interactive_authentication;
                goto parse_flag;
        case oKbdInteractiveAuthentication:
                intptr = &options->kbd_interactive_authentication;
                goto parse_flag;
@@ -357,27 +449,13 @@ 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;
-               goto parse_flag;
-#endif
-#ifdef AFS
-       case oAFSTokenPassing:
-               intptr = &options->afs_token_passing;
-               goto parse_flag;
-#endif
-       case oFallBackToRsh:
-               intptr = &options->fallback_to_rsh;
+
+       case oGssAuthentication:
+               intptr = &options->gss_authentication;
                goto parse_flag;
 
                goto parse_flag;
 
-       case oUseRsh:
-               intptr = &options->use_rsh;
+       case oGssDelegateCreds:
+               intptr = &options->gss_deleg_creds;
                goto parse_flag;
 
        case oBatchMode:
                goto parse_flag;
 
        case oBatchMode:
@@ -388,12 +466,17 @@ 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.",
-                             filename, linenum);
+                           filename, linenum);
                value = 0;      /* To avoid compiler warning... */
                if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
                        value = 1;
                value = 0;      /* To avoid compiler warning... */
                if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
                        value = 1;
@@ -411,8 +494,12 @@ 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:
+               intptr = &options->no_host_authentication_for_localhost;
                goto parse_flag;
 
        case oNumberOfPasswordPrompts:
                goto parse_flag;
 
        case oNumberOfPasswordPrompts:
@@ -423,6 +510,44 @@ parse_flag:
                intptr = &options->compression_level;
                goto parse_int;
 
                intptr = &options->compression_level;
                goto parse_int;
 
+       case oRekeyLimit:
+               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);
+               orig = val64 = strtoll(arg, &endofnumber, 10);
+               if (arg == endofnumber)
+                       fatal("%.200s line %d: Bad number.", filename, linenum);
+               switch (toupper(*endofnumber)) {
+               case '\0':
+                       scale = 1;
+                       break;
+               case 'K':
+                       scale = 1<<10;
+                       break;
+               case 'M':
+                       scale = 1<<20;
+                       break;
+               case 'G':
+                       scale = 1<<30;
+                       break;
+               default:
+                       fatal("%.200s line %d: Invalid RekeyLimit suffix",
+                           filename, linenum);
+               }
+               val64 *= scale;
+               /* detect integer wrap and too-large limits */
+               if ((val64 / scale) != orig || val64 > UINT_MAX)
+                       fatal("%.200s line %d: RekeyLimit too large",
+                           filename, linenum);
+               if (val64 < 16)
+                       fatal("%.200s line %d: RekeyLimit too small",
+                           filename, linenum);
+               if (*activep && options->rekey_limit == -1)
+                       options->rekey_limit = (u_int32_t)val64;
+               break;
+
        case oIdentityFile:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
        case oIdentityFile:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
@@ -431,8 +556,8 @@ parse_flag:
                        intptr = &options->num_identity_files;
                        if (*intptr >= SSH_MAX_IDENTITY_FILES)
                                fatal("%.200s line %d: Too many identity files specified (max %d).",
                        intptr = &options->num_identity_files;
                        if (*intptr >= SSH_MAX_IDENTITY_FILES)
                                fatal("%.200s line %d: Too many identity files specified (max %d).",
-                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
-                       charptr =  &options->identity_files[*intptr];
+                                   filename, linenum, SSH_MAX_IDENTITY_FILES);
+                       charptr = &options->identity_files[*intptr];
                        *charptr = xstrdup(arg);
                        *intptr = *intptr + 1;
                }
                        *charptr = xstrdup(arg);
                        *intptr = *intptr + 1;
                }
@@ -490,16 +615,12 @@ parse_string:
 
        case oProxyCommand:
                charptr = &options->proxy_command;
 
        case oProxyCommand:
                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);
-               }
+parse_command:
+               if (s == NULL)
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
+               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:
@@ -531,7 +652,7 @@ parse_int:
                value = cipher_number(arg);
                if (value == -1)
                        fatal("%.200s line %d: Bad cipher '%s'.",
                value = cipher_number(arg);
                if (value == -1)
                        fatal("%.200s line %d: Bad cipher '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && *intptr == -1)
                        *intptr = value;
                break;
                if (*activep && *intptr == -1)
                        *intptr = value;
                break;
@@ -542,7 +663,7 @@ parse_int:
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!ciphers_valid(arg))
                        fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!ciphers_valid(arg))
                        fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && options->ciphers == NULL)
                        options->ciphers = xstrdup(arg);
                break;
                if (*activep && options->ciphers == NULL)
                        options->ciphers = xstrdup(arg);
                break;
@@ -553,7 +674,7 @@ parse_int:
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!mac_valid(arg))
                        fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!mac_valid(arg))
                        fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && options->macs == NULL)
                        options->macs = xstrdup(arg);
                break;
                if (*activep && options->macs == NULL)
                        options->macs = xstrdup(arg);
                break;
@@ -564,7 +685,7 @@ parse_int:
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!key_names_valid2(arg))
                        fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!key_names_valid2(arg))
                        fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && options->hostkeyalgorithms == NULL)
                        options->hostkeyalgorithms = xstrdup(arg);
                break;
                if (*activep && options->hostkeyalgorithms == NULL)
                        options->hostkeyalgorithms = xstrdup(arg);
                break;
@@ -577,65 +698,58 @@ parse_int:
                value = proto_spec(arg);
                if (value == SSH_PROTO_UNKNOWN)
                        fatal("%.200s line %d: Bad protocol spec '%s'.",
                value = proto_spec(arg);
                if (value == SSH_PROTO_UNKNOWN)
                        fatal("%.200s line %d: Bad protocol spec '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && *intptr == SSH_PROTO_UNKNOWN)
                        *intptr = value;
                break;
 
        case oLogLevel:
                if (*activep && *intptr == SSH_PROTO_UNKNOWN)
                        *intptr = value;
                break;
 
        case oLogLevel:
-               intptr = (int *) &options->log_level;
+               log_level_ptr = &options->log_level;
                arg = strdelim(&s);
                value = log_level_number(arg);
                arg = strdelim(&s);
                value = log_level_number(arg);
-               if (value == (LogLevel) - 1)
+               if (value == SYSLOG_LEVEL_NOT_SET)
                        fatal("%.200s line %d: unsupported log level '%s'",
                        fatal("%.200s line %d: unsupported log level '%s'",
-                             filename, linenum, arg ? arg : "<NONE>");
-               if (*activep && (LogLevel) * intptr == -1)
-                       *intptr = (LogLevel) value;
+                           filename, linenum, arg ? arg : "<NONE>");
+               if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
+                       *log_level_ptr = (LogLevel) value;
                break;
 
        case oLocalForward:
        case oRemoteForward:
                break;
 
        case oLocalForward:
        case oRemoteForward:
+       case oDynamicForward:
                arg = strdelim(&s);
                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.",
-                           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)
+
+               if (opcode == oLocalForward ||
+                   opcode == oRemoteForward) {
+                       arg2 = strdelim(&s);
+                       if (arg2 == NULL || *arg2 == '\0')
+                               fatal("%.200s line %d: Missing target argument.",
+                                   filename, linenum);
+
+                       /* construct a string for parse_forward */
+                       snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
+               } else if (opcode == oDynamicForward) {
+                       strlcpy(fwdarg, arg, sizeof(fwdarg));
+               }
+
+               if (parse_forward(&fwd, fwdarg,
+                   opcode == oDynamicForward ? 1 : 0,
+                   opcode == oRemoteForward ? 1 : 0) == 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 (*activep) {
-                       if (opcode == oLocalForward)
-                               add_local_forward(options, fwd_port, buf,
-                                   fwd_host_port);
+                       if (opcode == oLocalForward ||
+                           opcode == oDynamicForward)
+                               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;
 
-       case oDynamicForward:
-               arg = strdelim(&s);
-               if (!arg || *arg == '\0')
-                       fatal("%.200s line %d: Missing port argument.",
-                           filename, linenum);
-               fwd_port = a2port(arg);
-               if (fwd_port == 0)
-                       fatal("%.200s line %d: Badly formatted port number.",
-                           filename, linenum);
-               if (*activep)
-                       add_local_forward(options, fwd_port, "socks4", 0);
-               break;
-
        case oClearAllForwardings:
                intptr = &options->clear_forwardings;
                goto parse_flag;
        case oClearAllForwardings:
                intptr = &options->clear_forwardings;
                goto parse_flag;
@@ -665,7 +779,7 @@ parse_int:
                        value = SSH_ESCAPECHAR_NONE;
                else {
                        fatal("%.200s line %d: Bad escape character.",
                        value = SSH_ESCAPECHAR_NONE;
                else {
                        fatal("%.200s line %d: Bad escape character.",
-                             filename, linenum);
+                           filename, linenum);
                        /* NOTREACHED */
                        value = 0;      /* Avoid compiler warning. */
                }
                        /* NOTREACHED */
                        value = 0;      /* Avoid compiler warning. */
                }
@@ -673,6 +787,148 @@ 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 oTunnel:
+               intptr = &options->tun_open;
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: Missing yes/point-to-point/"
+                           "ethernet/no argument.", filename, linenum);
+               value = 0;      /* silence compiler */
+               if (strcasecmp(arg, "ethernet") == 0)
+                       value = SSH_TUNMODE_ETHERNET;
+               else if (strcasecmp(arg, "point-to-point") == 0)
+                       value = SSH_TUNMODE_POINTOPOINT;
+               else if (strcasecmp(arg, "yes") == 0)
+                       value = SSH_TUNMODE_DEFAULT;
+               else if (strcasecmp(arg, "no") == 0)
+                       value = SSH_TUNMODE_NO;
+               else
+                       fatal("%s line %d: Bad yes/point-to-point/ethernet/"
+                           "no argument: %s", filename, linenum, arg);
+               if (*activep)
+                       *intptr = value;
+               break;
+
+       case oTunnelDevice:
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
+               value = a2tun(arg, &value2);
+               if (value == SSH_TUNID_ERR)
+                       fatal("%.200s line %d: Bad tun device.", filename, linenum);
+               if (*activep) {
+                       options->tun_local = value;
+                       options->tun_remote = value2;
+               }
+               break;
+
+       case oLocalCommand:
+               charptr = &options->local_command;
+               goto parse_command;
+
+       case oPermitLocalCommand:
+               intptr = &options->permit_local_command;
+               goto parse_flag;
+
+       case oVisualHostKey:
+               intptr = &options->visual_host_key;
+               goto parse_flag;
+
+       case oUseRoaming:
+               intptr = &options->use_roaming;
+               goto parse_flag;
+
+       case oDeprecated:
+               debug("%s line %d: Deprecated option \"%s\"",
+                   filename, linenum, keyword);
+               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);
        }
@@ -680,7 +936,7 @@ parse_int:
        /* Check that there is no garbage at end of line. */
        if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
                fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
        /* Check that there is no garbage at end of line. */
        if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
                fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
-                     filename, linenum, arg);
+                   filename, linenum, arg);
        }
        return 0;
 }
        }
        return 0;
 }
@@ -693,18 +949,27 @@ 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];
        int active, linenum;
        int bad_options = 0;
 
 {
        FILE *f;
        char line[1024];
        int active, linenum;
        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);
 
        /*
@@ -722,7 +987,7 @@ read_config_file(const char *filename, const char *host, Options *options)
        fclose(f);
        if (bad_options > 0)
                fatal("%s: terminating, %d bad configuration options",
        fclose(f);
        if (bad_options > 0)
                fatal("%s: terminating, %d bad configuration options",
-                     filename, bad_options);
+                   filename, bad_options);
        return 1;
 }
 
        return 1;
 }
 
@@ -739,37 +1004,31 @@ 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->exit_on_forward_failure = -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->rhosts_rsa_authentication = -1;
        options->hostbased_authentication = -1;
        options->password_authentication = -1;
        options->kbd_interactive_authentication = -1;
        options->kbd_interactive_devices = NULL;
        options->rhosts_rsa_authentication = -1;
        options->hostbased_authentication = -1;
-       options->fallback_to_rsh = -1;
-       options->use_rsh = -1;
        options->batch_mode = -1;
        options->check_host_ip = -1;
        options->strict_host_key_checking = -1;
        options->compression = -1;
        options->batch_mode = -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;
@@ -789,10 +1048,29 @@ initialize_options(Options * options)
        options->num_local_forwards = 0;
        options->num_remote_forwards = 0;
        options->clear_forwardings = -1;
        options->num_local_forwards = 0;
        options->num_remote_forwards = 0;
        options->clear_forwardings = -1;
-       options->log_level = (LogLevel) - 1;
+       options->log_level = SYSLOG_LEVEL_NOT_SET;
        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->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;
+       options->tun_open = -1;
+       options->tun_local = -1;
+       options->tun_remote = -1;
+       options->local_command = NULL;
+       options->permit_local_command = -1;
+       options->use_roaming = -1;
+       options->visual_host_key = -1;
+       options->zero_knowledge_password_authentication = -1;
 }
 
 /*
 }
 
 /*
@@ -809,46 +1087,34 @@ 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;
-#ifdef _PATH_XAUTH
+       if (options->forward_x11_trusted == -1)
+               options->forward_x11_trusted = 0;
+       if (options->exit_on_forward_failure == -1)
+               options->exit_on_forward_failure = 0;
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
-#endif
        if (options->gateway_ports == -1)
                options->gateway_ports = 0;
        if (options->use_privileged_port == -1)
                options->use_privileged_port = 0;
        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->hostbased_authentication == -1)
                options->hostbased_authentication = 0;
-       if (options->fallback_to_rsh == -1)
-               options->fallback_to_rsh = 0;
-       if (options->use_rsh == -1)
-               options->use_rsh = 0;
        if (options->batch_mode == -1)
                options->batch_mode = 0;
        if (options->check_host_ip == -1)
        if (options->batch_mode == -1)
                options->batch_mode = 0;
        if (options->check_host_ip == -1)
@@ -857,12 +1123,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)
@@ -874,7 +1142,7 @@ fill_default_options(Options * options)
        /* options->macs, default set in myproposals.h */
        /* options->hostkeyalgorithms, default set in myproposals.h */
        if (options->protocol == SSH_PROTO_UNKNOWN)
        /* options->macs, default set in myproposals.h */
        /* options->hostkeyalgorithms, default set in myproposals.h */
        if (options->protocol == SSH_PROTO_UNKNOWN)
-               options->protocol = SSH_PROTO_1|SSH_PROTO_2;
+               options->protocol = SSH_PROTO_2;
        if (options->num_identity_files == 0) {
                if (options->protocol & SSH_PROTO_1) {
                        len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
        if (options->num_identity_files == 0) {
                if (options->protocol & SSH_PROTO_1) {
                        len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
@@ -907,13 +1175,144 @@ fill_default_options(Options * options)
                options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
        if (options->user_hostfile2 == NULL)
                options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
                options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
        if (options->user_hostfile2 == NULL)
                options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
-       if (options->log_level == (LogLevel) - 1)
+       if (options->log_level == SYSLOG_LEVEL_NOT_SET)
                options->log_level = SYSLOG_LEVEL_INFO;
        if (options->clear_forwardings == 1)
                clear_forwardings(options);
                options->log_level = SYSLOG_LEVEL_INFO;
        if (options->clear_forwardings == 1)
                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;
+       if (options->tun_open == -1)
+               options->tun_open = SSH_TUNMODE_NO;
+       if (options->tun_local == -1)
+               options->tun_local = SSH_TUNID_ANY;
+       if (options->tun_remote == -1)
+               options->tun_remote = SSH_TUNID_ANY;
+       if (options->permit_local_command == -1)
+               options->permit_local_command = 0;
+       if (options->use_roaming == -1)
+               options->use_roaming = 1;
+       if (options->visual_host_key == -1)
+               options->visual_host_key = 0;
+       if (options->zero_knowledge_password_authentication == -1)
+               options->zero_knowledge_password_authentication = 0;
+       /* options->local_command should not be set by default */
        /* 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:
+ *   dynamicfwd == 0
+ *     [listenhost:]listenport:connecthost:connectport
+ *   dynamicfwd == 1
+ *     [listenhost:]listenport
+ * returns number of arguments parsed or zero on error
+ */
+int
+parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
+{
+       int i;
+       char *p, *cp, *fwdarg[4];
+
+       memset(fwd, '\0', sizeof(*fwd));
+
+       cp = p = xstrdup(fwdspec);
+
+       /* skip leading spaces */
+       while (isspace(*cp))
+               cp++;
+
+       for (i = 0; i < 4; ++i)
+               if ((fwdarg[i] = hpdelim(&cp)) == NULL)
+                       break;
+
+       /* Check for trailing garbage */
+       if (cp != NULL)
+               i = 0;  /* failure */
+
+       switch (i) {
+       case 1:
+               fwd->listen_host = NULL;
+               fwd->listen_port = a2port(fwdarg[0]);
+               fwd->connect_host = xstrdup("socks");
+               break;
+
+       case 2:
+               fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
+               fwd->listen_port = a2port(fwdarg[1]);
+               fwd->connect_host = xstrdup("socks");
+               break;
+
+       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 (dynamicfwd) {
+               if (!(i == 1 || i == 2))
+                       goto fail_free;
+       } else {
+               if (!(i == 3 || i == 4))
+                       goto fail_free;
+               if (fwd->connect_port <= 0)
+                       goto fail_free;
+       }
+
+       if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
+               goto fail_free;
+
+       if (fwd->connect_host != NULL &&
+           strlen(fwd->connect_host) >= NI_MAXHOST)
+               goto fail_free;
+       if (fwd->listen_host != NULL &&
+           strlen(fwd->listen_host) >= NI_MAXHOST)
+               goto fail_free;
+
+
+       return (i);
+
+ fail_free:
+       if (fwd->connect_host != NULL) {
+               xfree(fwd->connect_host);
+               fwd->connect_host = NULL;
+       }
+       if (fwd->listen_host != NULL) {
+               xfree(fwd->listen_host);
+               fwd->listen_host = NULL;
+       }
+       return (0);
+}
This page took 1.862523 seconds and 4 git commands to generate.