1*cb5eb4f1SPeter Avalos /* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */ 218de8d7fSPeter Avalos /* 318de8d7fSPeter Avalos * Author: Tatu Ylonen <ylo@cs.hut.fi> 418de8d7fSPeter Avalos * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 518de8d7fSPeter Avalos * All rights reserved 618de8d7fSPeter Avalos * Functions for reading the configuration files. 718de8d7fSPeter Avalos * 818de8d7fSPeter Avalos * As far as I am concerned, the code I have written for this software 918de8d7fSPeter Avalos * can be used freely for any purpose. Any derived versions of this 1018de8d7fSPeter Avalos * software must be clearly marked as such, and if the derived work is 1118de8d7fSPeter Avalos * incompatible with the protocol description in the RFC file, it must be 1218de8d7fSPeter Avalos * called by a name other than "ssh" or "Secure Shell". 1318de8d7fSPeter Avalos */ 1418de8d7fSPeter Avalos 1518de8d7fSPeter Avalos #include "includes.h" 1618de8d7fSPeter Avalos 1718de8d7fSPeter Avalos #include <sys/types.h> 1818de8d7fSPeter Avalos #include <sys/stat.h> 1918de8d7fSPeter Avalos #include <sys/socket.h> 2018de8d7fSPeter Avalos 2118de8d7fSPeter Avalos #include <netinet/in.h> 2218de8d7fSPeter Avalos 2318de8d7fSPeter Avalos #include <ctype.h> 2418de8d7fSPeter Avalos #include <errno.h> 2518de8d7fSPeter Avalos #include <netdb.h> 2618de8d7fSPeter Avalos #include <signal.h> 2718de8d7fSPeter Avalos #include <stdarg.h> 2818de8d7fSPeter Avalos #include <stdio.h> 2918de8d7fSPeter Avalos #include <string.h> 3018de8d7fSPeter Avalos #include <unistd.h> 3118de8d7fSPeter Avalos 3218de8d7fSPeter Avalos #include "xmalloc.h" 3318de8d7fSPeter Avalos #include "ssh.h" 3418de8d7fSPeter Avalos #include "compat.h" 3518de8d7fSPeter Avalos #include "cipher.h" 3618de8d7fSPeter Avalos #include "pathnames.h" 3718de8d7fSPeter Avalos #include "log.h" 3818de8d7fSPeter Avalos #include "key.h" 3918de8d7fSPeter Avalos #include "readconf.h" 4018de8d7fSPeter Avalos #include "match.h" 4118de8d7fSPeter Avalos #include "misc.h" 4218de8d7fSPeter Avalos #include "buffer.h" 4318de8d7fSPeter Avalos #include "kex.h" 4418de8d7fSPeter Avalos #include "mac.h" 4518de8d7fSPeter Avalos 4618de8d7fSPeter Avalos /* Format of the configuration file: 4718de8d7fSPeter Avalos 4818de8d7fSPeter Avalos # Configuration data is parsed as follows: 4918de8d7fSPeter Avalos # 1. command line options 5018de8d7fSPeter Avalos # 2. user-specific file 5118de8d7fSPeter Avalos # 3. system-wide file 5218de8d7fSPeter Avalos # Any configuration value is only changed the first time it is set. 5318de8d7fSPeter Avalos # Thus, host-specific definitions should be at the beginning of the 5418de8d7fSPeter Avalos # configuration file, and defaults at the end. 5518de8d7fSPeter Avalos 5618de8d7fSPeter Avalos # Host-specific declarations. These may override anything above. A single 5718de8d7fSPeter Avalos # host may match multiple declarations; these are processed in the order 5818de8d7fSPeter Avalos # that they are given in. 5918de8d7fSPeter Avalos 6018de8d7fSPeter Avalos Host *.ngs.fi ngs.fi 6118de8d7fSPeter Avalos User foo 6218de8d7fSPeter Avalos 6318de8d7fSPeter Avalos Host fake.com 6418de8d7fSPeter Avalos HostName another.host.name.real.org 6518de8d7fSPeter Avalos User blaah 6618de8d7fSPeter Avalos Port 34289 6718de8d7fSPeter Avalos ForwardX11 no 6818de8d7fSPeter Avalos ForwardAgent no 6918de8d7fSPeter Avalos 7018de8d7fSPeter Avalos Host books.com 7118de8d7fSPeter Avalos RemoteForward 9999 shadows.cs.hut.fi:9999 7218de8d7fSPeter Avalos Cipher 3des 7318de8d7fSPeter Avalos 7418de8d7fSPeter Avalos Host fascist.blob.com 7518de8d7fSPeter Avalos Port 23123 7618de8d7fSPeter Avalos User tylonen 7718de8d7fSPeter Avalos PasswordAuthentication no 7818de8d7fSPeter Avalos 7918de8d7fSPeter Avalos Host puukko.hut.fi 8018de8d7fSPeter Avalos User t35124p 8118de8d7fSPeter Avalos ProxyCommand ssh-proxy %h %p 8218de8d7fSPeter Avalos 8318de8d7fSPeter Avalos Host *.fr 8418de8d7fSPeter Avalos PublicKeyAuthentication no 8518de8d7fSPeter Avalos 8618de8d7fSPeter Avalos Host *.su 8718de8d7fSPeter Avalos Cipher none 8818de8d7fSPeter Avalos PasswordAuthentication no 8918de8d7fSPeter Avalos 9018de8d7fSPeter Avalos Host vpn.fake.com 9118de8d7fSPeter Avalos Tunnel yes 9218de8d7fSPeter Avalos TunnelDevice 3 9318de8d7fSPeter Avalos 9418de8d7fSPeter Avalos # Defaults for various options 9518de8d7fSPeter Avalos Host * 9618de8d7fSPeter Avalos ForwardAgent no 9718de8d7fSPeter Avalos ForwardX11 no 9818de8d7fSPeter Avalos PasswordAuthentication yes 9918de8d7fSPeter Avalos RSAAuthentication yes 10018de8d7fSPeter Avalos RhostsRSAAuthentication yes 10118de8d7fSPeter Avalos StrictHostKeyChecking yes 10218de8d7fSPeter Avalos TcpKeepAlive no 10318de8d7fSPeter Avalos IdentityFile ~/.ssh/identity 10418de8d7fSPeter Avalos Port 22 10518de8d7fSPeter Avalos EscapeChar ~ 10618de8d7fSPeter Avalos 10718de8d7fSPeter Avalos */ 10818de8d7fSPeter Avalos 10918de8d7fSPeter Avalos /* Keyword tokens. */ 11018de8d7fSPeter Avalos 11118de8d7fSPeter Avalos typedef enum { 11218de8d7fSPeter Avalos oBadOption, 11318de8d7fSPeter Avalos oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts, 11418de8d7fSPeter Avalos oExitOnForwardFailure, 11518de8d7fSPeter Avalos oPasswordAuthentication, oRSAAuthentication, 11618de8d7fSPeter Avalos oChallengeResponseAuthentication, oXAuthLocation, 11718de8d7fSPeter Avalos oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 11818de8d7fSPeter Avalos oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 11918de8d7fSPeter Avalos oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 12018de8d7fSPeter Avalos oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 12118de8d7fSPeter Avalos oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 12218de8d7fSPeter Avalos oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 12318de8d7fSPeter Avalos oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 12418de8d7fSPeter Avalos oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 12518de8d7fSPeter Avalos oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 12618de8d7fSPeter Avalos oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, 12718de8d7fSPeter Avalos oClearAllForwardings, oNoHostAuthenticationForLocalhost, 12818de8d7fSPeter Avalos oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 12918de8d7fSPeter Avalos oAddressFamily, oGssAuthentication, oGssDelegateCreds, 13018de8d7fSPeter Avalos oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 13118de8d7fSPeter Avalos oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, 13218de8d7fSPeter Avalos oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 133*cb5eb4f1SPeter Avalos oVisualHostKey, oZeroKnowledgePasswordAuthentication, 13418de8d7fSPeter Avalos oDeprecated, oUnsupported 13518de8d7fSPeter Avalos } OpCodes; 13618de8d7fSPeter Avalos 13718de8d7fSPeter Avalos /* Textual representations of the tokens. */ 13818de8d7fSPeter Avalos 13918de8d7fSPeter Avalos static struct { 14018de8d7fSPeter Avalos const char *name; 14118de8d7fSPeter Avalos OpCodes opcode; 14218de8d7fSPeter Avalos } keywords[] = { 14318de8d7fSPeter Avalos { "forwardagent", oForwardAgent }, 14418de8d7fSPeter Avalos { "forwardx11", oForwardX11 }, 14518de8d7fSPeter Avalos { "forwardx11trusted", oForwardX11Trusted }, 14618de8d7fSPeter Avalos { "exitonforwardfailure", oExitOnForwardFailure }, 14718de8d7fSPeter Avalos { "xauthlocation", oXAuthLocation }, 14818de8d7fSPeter Avalos { "gatewayports", oGatewayPorts }, 14918de8d7fSPeter Avalos { "useprivilegedport", oUsePrivilegedPort }, 15018de8d7fSPeter Avalos { "rhostsauthentication", oDeprecated }, 15118de8d7fSPeter Avalos { "passwordauthentication", oPasswordAuthentication }, 15218de8d7fSPeter Avalos { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 15318de8d7fSPeter Avalos { "kbdinteractivedevices", oKbdInteractiveDevices }, 15418de8d7fSPeter Avalos { "rsaauthentication", oRSAAuthentication }, 15518de8d7fSPeter Avalos { "pubkeyauthentication", oPubkeyAuthentication }, 15618de8d7fSPeter Avalos { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 15718de8d7fSPeter Avalos { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 15818de8d7fSPeter Avalos { "hostbasedauthentication", oHostbasedAuthentication }, 15918de8d7fSPeter Avalos { "challengeresponseauthentication", oChallengeResponseAuthentication }, 16018de8d7fSPeter Avalos { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 16118de8d7fSPeter Avalos { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 16218de8d7fSPeter Avalos { "kerberosauthentication", oUnsupported }, 16318de8d7fSPeter Avalos { "kerberostgtpassing", oUnsupported }, 16418de8d7fSPeter Avalos { "afstokenpassing", oUnsupported }, 16518de8d7fSPeter Avalos #if defined(GSSAPI) 16618de8d7fSPeter Avalos { "gssapiauthentication", oGssAuthentication }, 16718de8d7fSPeter Avalos { "gssapidelegatecredentials", oGssDelegateCreds }, 16818de8d7fSPeter Avalos #else 16918de8d7fSPeter Avalos { "gssapiauthentication", oUnsupported }, 17018de8d7fSPeter Avalos { "gssapidelegatecredentials", oUnsupported }, 17118de8d7fSPeter Avalos #endif 17218de8d7fSPeter Avalos { "fallbacktorsh", oDeprecated }, 17318de8d7fSPeter Avalos { "usersh", oDeprecated }, 17418de8d7fSPeter Avalos { "identityfile", oIdentityFile }, 175*cb5eb4f1SPeter Avalos { "identityfile2", oIdentityFile }, /* obsolete */ 17618de8d7fSPeter Avalos { "identitiesonly", oIdentitiesOnly }, 17718de8d7fSPeter Avalos { "hostname", oHostName }, 17818de8d7fSPeter Avalos { "hostkeyalias", oHostKeyAlias }, 17918de8d7fSPeter Avalos { "proxycommand", oProxyCommand }, 18018de8d7fSPeter Avalos { "port", oPort }, 18118de8d7fSPeter Avalos { "cipher", oCipher }, 18218de8d7fSPeter Avalos { "ciphers", oCiphers }, 18318de8d7fSPeter Avalos { "macs", oMacs }, 18418de8d7fSPeter Avalos { "protocol", oProtocol }, 18518de8d7fSPeter Avalos { "remoteforward", oRemoteForward }, 18618de8d7fSPeter Avalos { "localforward", oLocalForward }, 18718de8d7fSPeter Avalos { "user", oUser }, 18818de8d7fSPeter Avalos { "host", oHost }, 18918de8d7fSPeter Avalos { "escapechar", oEscapeChar }, 19018de8d7fSPeter Avalos { "globalknownhostsfile", oGlobalKnownHostsFile }, 191*cb5eb4f1SPeter Avalos { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, /* obsolete */ 192*cb5eb4f1SPeter Avalos { "userknownhostsfile", oUserKnownHostsFile }, 19318de8d7fSPeter Avalos { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ 19418de8d7fSPeter Avalos { "connectionattempts", oConnectionAttempts }, 19518de8d7fSPeter Avalos { "batchmode", oBatchMode }, 19618de8d7fSPeter Avalos { "checkhostip", oCheckHostIP }, 19718de8d7fSPeter Avalos { "stricthostkeychecking", oStrictHostKeyChecking }, 19818de8d7fSPeter Avalos { "compression", oCompression }, 19918de8d7fSPeter Avalos { "compressionlevel", oCompressionLevel }, 20018de8d7fSPeter Avalos { "tcpkeepalive", oTCPKeepAlive }, 20118de8d7fSPeter Avalos { "keepalive", oTCPKeepAlive }, /* obsolete */ 20218de8d7fSPeter Avalos { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 20318de8d7fSPeter Avalos { "loglevel", oLogLevel }, 20418de8d7fSPeter Avalos { "dynamicforward", oDynamicForward }, 20518de8d7fSPeter Avalos { "preferredauthentications", oPreferredAuthentications }, 20618de8d7fSPeter Avalos { "hostkeyalgorithms", oHostKeyAlgorithms }, 20718de8d7fSPeter Avalos { "bindaddress", oBindAddress }, 20818de8d7fSPeter Avalos #ifdef SMARTCARD 20918de8d7fSPeter Avalos { "smartcarddevice", oSmartcardDevice }, 21018de8d7fSPeter Avalos #else 21118de8d7fSPeter Avalos { "smartcarddevice", oUnsupported }, 21218de8d7fSPeter Avalos #endif 21318de8d7fSPeter Avalos { "clearallforwardings", oClearAllForwardings }, 21418de8d7fSPeter Avalos { "enablesshkeysign", oEnableSSHKeysign }, 21518de8d7fSPeter Avalos { "verifyhostkeydns", oVerifyHostKeyDNS }, 21618de8d7fSPeter Avalos { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 21718de8d7fSPeter Avalos { "rekeylimit", oRekeyLimit }, 21818de8d7fSPeter Avalos { "connecttimeout", oConnectTimeout }, 21918de8d7fSPeter Avalos { "addressfamily", oAddressFamily }, 22018de8d7fSPeter Avalos { "serveraliveinterval", oServerAliveInterval }, 22118de8d7fSPeter Avalos { "serveralivecountmax", oServerAliveCountMax }, 22218de8d7fSPeter Avalos { "sendenv", oSendEnv }, 22318de8d7fSPeter Avalos { "controlpath", oControlPath }, 22418de8d7fSPeter Avalos { "controlmaster", oControlMaster }, 22518de8d7fSPeter Avalos { "hashknownhosts", oHashKnownHosts }, 22618de8d7fSPeter Avalos { "tunnel", oTunnel }, 22718de8d7fSPeter Avalos { "tunneldevice", oTunnelDevice }, 22818de8d7fSPeter Avalos { "localcommand", oLocalCommand }, 22918de8d7fSPeter Avalos { "permitlocalcommand", oPermitLocalCommand }, 23018de8d7fSPeter Avalos { "visualhostkey", oVisualHostKey }, 231*cb5eb4f1SPeter Avalos #ifdef JPAKE 232*cb5eb4f1SPeter Avalos { "zeroknowledgepasswordauthentication", 233*cb5eb4f1SPeter Avalos oZeroKnowledgePasswordAuthentication }, 234*cb5eb4f1SPeter Avalos #else 235*cb5eb4f1SPeter Avalos { "zeroknowledgepasswordauthentication", oUnsupported }, 236*cb5eb4f1SPeter Avalos #endif 237*cb5eb4f1SPeter Avalos 23818de8d7fSPeter Avalos { NULL, oBadOption } 23918de8d7fSPeter Avalos }; 24018de8d7fSPeter Avalos 24118de8d7fSPeter Avalos /* 24218de8d7fSPeter Avalos * Adds a local TCP/IP port forward to options. Never returns if there is an 24318de8d7fSPeter Avalos * error. 24418de8d7fSPeter Avalos */ 24518de8d7fSPeter Avalos 24618de8d7fSPeter Avalos void 24718de8d7fSPeter Avalos add_local_forward(Options *options, const Forward *newfwd) 24818de8d7fSPeter Avalos { 24918de8d7fSPeter Avalos Forward *fwd; 25018de8d7fSPeter Avalos #ifndef NO_IPPORT_RESERVED_CONCEPT 25118de8d7fSPeter Avalos extern uid_t original_real_uid; 25218de8d7fSPeter Avalos if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0) 25318de8d7fSPeter Avalos fatal("Privileged ports can only be forwarded by root."); 25418de8d7fSPeter Avalos #endif 25518de8d7fSPeter Avalos if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 25618de8d7fSPeter Avalos fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 25718de8d7fSPeter Avalos fwd = &options->local_forwards[options->num_local_forwards++]; 25818de8d7fSPeter Avalos 259*cb5eb4f1SPeter Avalos fwd->listen_host = newfwd->listen_host; 26018de8d7fSPeter Avalos fwd->listen_port = newfwd->listen_port; 261*cb5eb4f1SPeter Avalos fwd->connect_host = newfwd->connect_host; 26218de8d7fSPeter Avalos fwd->connect_port = newfwd->connect_port; 26318de8d7fSPeter Avalos } 26418de8d7fSPeter Avalos 26518de8d7fSPeter Avalos /* 26618de8d7fSPeter Avalos * Adds a remote TCP/IP port forward to options. Never returns if there is 26718de8d7fSPeter Avalos * an error. 26818de8d7fSPeter Avalos */ 26918de8d7fSPeter Avalos 27018de8d7fSPeter Avalos void 27118de8d7fSPeter Avalos add_remote_forward(Options *options, const Forward *newfwd) 27218de8d7fSPeter Avalos { 27318de8d7fSPeter Avalos Forward *fwd; 27418de8d7fSPeter Avalos if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 27518de8d7fSPeter Avalos fatal("Too many remote forwards (max %d).", 27618de8d7fSPeter Avalos SSH_MAX_FORWARDS_PER_DIRECTION); 27718de8d7fSPeter Avalos fwd = &options->remote_forwards[options->num_remote_forwards++]; 27818de8d7fSPeter Avalos 279*cb5eb4f1SPeter Avalos fwd->listen_host = newfwd->listen_host; 28018de8d7fSPeter Avalos fwd->listen_port = newfwd->listen_port; 281*cb5eb4f1SPeter Avalos fwd->connect_host = newfwd->connect_host; 28218de8d7fSPeter Avalos fwd->connect_port = newfwd->connect_port; 28318de8d7fSPeter Avalos } 28418de8d7fSPeter Avalos 28518de8d7fSPeter Avalos static void 28618de8d7fSPeter Avalos clear_forwardings(Options *options) 28718de8d7fSPeter Avalos { 28818de8d7fSPeter Avalos int i; 28918de8d7fSPeter Avalos 29018de8d7fSPeter Avalos for (i = 0; i < options->num_local_forwards; i++) { 29118de8d7fSPeter Avalos if (options->local_forwards[i].listen_host != NULL) 29218de8d7fSPeter Avalos xfree(options->local_forwards[i].listen_host); 29318de8d7fSPeter Avalos xfree(options->local_forwards[i].connect_host); 29418de8d7fSPeter Avalos } 29518de8d7fSPeter Avalos options->num_local_forwards = 0; 29618de8d7fSPeter Avalos for (i = 0; i < options->num_remote_forwards; i++) { 29718de8d7fSPeter Avalos if (options->remote_forwards[i].listen_host != NULL) 29818de8d7fSPeter Avalos xfree(options->remote_forwards[i].listen_host); 29918de8d7fSPeter Avalos xfree(options->remote_forwards[i].connect_host); 30018de8d7fSPeter Avalos } 30118de8d7fSPeter Avalos options->num_remote_forwards = 0; 30218de8d7fSPeter Avalos options->tun_open = SSH_TUNMODE_NO; 30318de8d7fSPeter Avalos } 30418de8d7fSPeter Avalos 30518de8d7fSPeter Avalos /* 30618de8d7fSPeter Avalos * Returns the number of the token pointed to by cp or oBadOption. 30718de8d7fSPeter Avalos */ 30818de8d7fSPeter Avalos 30918de8d7fSPeter Avalos static OpCodes 31018de8d7fSPeter Avalos parse_token(const char *cp, const char *filename, int linenum) 31118de8d7fSPeter Avalos { 31218de8d7fSPeter Avalos u_int i; 31318de8d7fSPeter Avalos 31418de8d7fSPeter Avalos for (i = 0; keywords[i].name; i++) 31518de8d7fSPeter Avalos if (strcasecmp(cp, keywords[i].name) == 0) 31618de8d7fSPeter Avalos return keywords[i].opcode; 31718de8d7fSPeter Avalos 31818de8d7fSPeter Avalos error("%s: line %d: Bad configuration option: %s", 31918de8d7fSPeter Avalos filename, linenum, cp); 32018de8d7fSPeter Avalos return oBadOption; 32118de8d7fSPeter Avalos } 32218de8d7fSPeter Avalos 32318de8d7fSPeter Avalos /* 32418de8d7fSPeter Avalos * Processes a single option line as used in the configuration files. This 32518de8d7fSPeter Avalos * only sets those values that have not already been set. 32618de8d7fSPeter Avalos */ 32718de8d7fSPeter Avalos #define WHITESPACE " \t\r\n" 32818de8d7fSPeter Avalos 32918de8d7fSPeter Avalos int 33018de8d7fSPeter Avalos process_config_line(Options *options, const char *host, 33118de8d7fSPeter Avalos char *line, const char *filename, int linenum, 33218de8d7fSPeter Avalos int *activep) 33318de8d7fSPeter Avalos { 33418de8d7fSPeter Avalos char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; 33518de8d7fSPeter Avalos int opcode, *intptr, value, value2, scale; 33618de8d7fSPeter Avalos LogLevel *log_level_ptr; 33718de8d7fSPeter Avalos long long orig, val64; 33818de8d7fSPeter Avalos size_t len; 33918de8d7fSPeter Avalos Forward fwd; 34018de8d7fSPeter Avalos 34118de8d7fSPeter Avalos /* Strip trailing whitespace */ 34218de8d7fSPeter Avalos for (len = strlen(line) - 1; len > 0; len--) { 34318de8d7fSPeter Avalos if (strchr(WHITESPACE, line[len]) == NULL) 34418de8d7fSPeter Avalos break; 34518de8d7fSPeter Avalos line[len] = '\0'; 34618de8d7fSPeter Avalos } 34718de8d7fSPeter Avalos 34818de8d7fSPeter Avalos s = line; 34918de8d7fSPeter Avalos /* Get the keyword. (Each line is supposed to begin with a keyword). */ 35018de8d7fSPeter Avalos if ((keyword = strdelim(&s)) == NULL) 35118de8d7fSPeter Avalos return 0; 35218de8d7fSPeter Avalos /* Ignore leading whitespace. */ 35318de8d7fSPeter Avalos if (*keyword == '\0') 35418de8d7fSPeter Avalos keyword = strdelim(&s); 35518de8d7fSPeter Avalos if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 35618de8d7fSPeter Avalos return 0; 35718de8d7fSPeter Avalos 35818de8d7fSPeter Avalos opcode = parse_token(keyword, filename, linenum); 35918de8d7fSPeter Avalos 36018de8d7fSPeter Avalos switch (opcode) { 36118de8d7fSPeter Avalos case oBadOption: 36218de8d7fSPeter Avalos /* don't panic, but count bad options */ 36318de8d7fSPeter Avalos return -1; 36418de8d7fSPeter Avalos /* NOTREACHED */ 36518de8d7fSPeter Avalos case oConnectTimeout: 36618de8d7fSPeter Avalos intptr = &options->connection_timeout; 36718de8d7fSPeter Avalos parse_time: 36818de8d7fSPeter Avalos arg = strdelim(&s); 36918de8d7fSPeter Avalos if (!arg || *arg == '\0') 37018de8d7fSPeter Avalos fatal("%s line %d: missing time value.", 37118de8d7fSPeter Avalos filename, linenum); 37218de8d7fSPeter Avalos if ((value = convtime(arg)) == -1) 37318de8d7fSPeter Avalos fatal("%s line %d: invalid time value.", 37418de8d7fSPeter Avalos filename, linenum); 37518de8d7fSPeter Avalos if (*activep && *intptr == -1) 37618de8d7fSPeter Avalos *intptr = value; 37718de8d7fSPeter Avalos break; 37818de8d7fSPeter Avalos 37918de8d7fSPeter Avalos case oForwardAgent: 38018de8d7fSPeter Avalos intptr = &options->forward_agent; 38118de8d7fSPeter Avalos parse_flag: 38218de8d7fSPeter Avalos arg = strdelim(&s); 38318de8d7fSPeter Avalos if (!arg || *arg == '\0') 38418de8d7fSPeter Avalos fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 38518de8d7fSPeter Avalos value = 0; /* To avoid compiler warning... */ 38618de8d7fSPeter Avalos if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 38718de8d7fSPeter Avalos value = 1; 38818de8d7fSPeter Avalos else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 38918de8d7fSPeter Avalos value = 0; 39018de8d7fSPeter Avalos else 39118de8d7fSPeter Avalos fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 39218de8d7fSPeter Avalos if (*activep && *intptr == -1) 39318de8d7fSPeter Avalos *intptr = value; 39418de8d7fSPeter Avalos break; 39518de8d7fSPeter Avalos 39618de8d7fSPeter Avalos case oForwardX11: 39718de8d7fSPeter Avalos intptr = &options->forward_x11; 39818de8d7fSPeter Avalos goto parse_flag; 39918de8d7fSPeter Avalos 40018de8d7fSPeter Avalos case oForwardX11Trusted: 40118de8d7fSPeter Avalos intptr = &options->forward_x11_trusted; 40218de8d7fSPeter Avalos goto parse_flag; 40318de8d7fSPeter Avalos 40418de8d7fSPeter Avalos case oGatewayPorts: 40518de8d7fSPeter Avalos intptr = &options->gateway_ports; 40618de8d7fSPeter Avalos goto parse_flag; 40718de8d7fSPeter Avalos 40818de8d7fSPeter Avalos case oExitOnForwardFailure: 40918de8d7fSPeter Avalos intptr = &options->exit_on_forward_failure; 41018de8d7fSPeter Avalos goto parse_flag; 41118de8d7fSPeter Avalos 41218de8d7fSPeter Avalos case oUsePrivilegedPort: 41318de8d7fSPeter Avalos intptr = &options->use_privileged_port; 41418de8d7fSPeter Avalos goto parse_flag; 41518de8d7fSPeter Avalos 41618de8d7fSPeter Avalos case oPasswordAuthentication: 41718de8d7fSPeter Avalos intptr = &options->password_authentication; 41818de8d7fSPeter Avalos goto parse_flag; 41918de8d7fSPeter Avalos 420*cb5eb4f1SPeter Avalos case oZeroKnowledgePasswordAuthentication: 421*cb5eb4f1SPeter Avalos intptr = &options->zero_knowledge_password_authentication; 422*cb5eb4f1SPeter Avalos goto parse_flag; 423*cb5eb4f1SPeter Avalos 42418de8d7fSPeter Avalos case oKbdInteractiveAuthentication: 42518de8d7fSPeter Avalos intptr = &options->kbd_interactive_authentication; 42618de8d7fSPeter Avalos goto parse_flag; 42718de8d7fSPeter Avalos 42818de8d7fSPeter Avalos case oKbdInteractiveDevices: 42918de8d7fSPeter Avalos charptr = &options->kbd_interactive_devices; 43018de8d7fSPeter Avalos goto parse_string; 43118de8d7fSPeter Avalos 43218de8d7fSPeter Avalos case oPubkeyAuthentication: 43318de8d7fSPeter Avalos intptr = &options->pubkey_authentication; 43418de8d7fSPeter Avalos goto parse_flag; 43518de8d7fSPeter Avalos 43618de8d7fSPeter Avalos case oRSAAuthentication: 43718de8d7fSPeter Avalos intptr = &options->rsa_authentication; 43818de8d7fSPeter Avalos goto parse_flag; 43918de8d7fSPeter Avalos 44018de8d7fSPeter Avalos case oRhostsRSAAuthentication: 44118de8d7fSPeter Avalos intptr = &options->rhosts_rsa_authentication; 44218de8d7fSPeter Avalos goto parse_flag; 44318de8d7fSPeter Avalos 44418de8d7fSPeter Avalos case oHostbasedAuthentication: 44518de8d7fSPeter Avalos intptr = &options->hostbased_authentication; 44618de8d7fSPeter Avalos goto parse_flag; 44718de8d7fSPeter Avalos 44818de8d7fSPeter Avalos case oChallengeResponseAuthentication: 44918de8d7fSPeter Avalos intptr = &options->challenge_response_authentication; 45018de8d7fSPeter Avalos goto parse_flag; 45118de8d7fSPeter Avalos 45218de8d7fSPeter Avalos case oGssAuthentication: 45318de8d7fSPeter Avalos intptr = &options->gss_authentication; 45418de8d7fSPeter Avalos goto parse_flag; 45518de8d7fSPeter Avalos 45618de8d7fSPeter Avalos case oGssDelegateCreds: 45718de8d7fSPeter Avalos intptr = &options->gss_deleg_creds; 45818de8d7fSPeter Avalos goto parse_flag; 45918de8d7fSPeter Avalos 46018de8d7fSPeter Avalos case oBatchMode: 46118de8d7fSPeter Avalos intptr = &options->batch_mode; 46218de8d7fSPeter Avalos goto parse_flag; 46318de8d7fSPeter Avalos 46418de8d7fSPeter Avalos case oCheckHostIP: 46518de8d7fSPeter Avalos intptr = &options->check_host_ip; 46618de8d7fSPeter Avalos goto parse_flag; 46718de8d7fSPeter Avalos 46818de8d7fSPeter Avalos case oVerifyHostKeyDNS: 46918de8d7fSPeter Avalos intptr = &options->verify_host_key_dns; 47018de8d7fSPeter Avalos goto parse_yesnoask; 47118de8d7fSPeter Avalos 47218de8d7fSPeter Avalos case oStrictHostKeyChecking: 47318de8d7fSPeter Avalos intptr = &options->strict_host_key_checking; 47418de8d7fSPeter Avalos parse_yesnoask: 47518de8d7fSPeter Avalos arg = strdelim(&s); 47618de8d7fSPeter Avalos if (!arg || *arg == '\0') 47718de8d7fSPeter Avalos fatal("%.200s line %d: Missing yes/no/ask argument.", 47818de8d7fSPeter Avalos filename, linenum); 47918de8d7fSPeter Avalos value = 0; /* To avoid compiler warning... */ 48018de8d7fSPeter Avalos if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 48118de8d7fSPeter Avalos value = 1; 48218de8d7fSPeter Avalos else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 48318de8d7fSPeter Avalos value = 0; 48418de8d7fSPeter Avalos else if (strcmp(arg, "ask") == 0) 48518de8d7fSPeter Avalos value = 2; 48618de8d7fSPeter Avalos else 48718de8d7fSPeter Avalos fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 48818de8d7fSPeter Avalos if (*activep && *intptr == -1) 48918de8d7fSPeter Avalos *intptr = value; 49018de8d7fSPeter Avalos break; 49118de8d7fSPeter Avalos 49218de8d7fSPeter Avalos case oCompression: 49318de8d7fSPeter Avalos intptr = &options->compression; 49418de8d7fSPeter Avalos goto parse_flag; 49518de8d7fSPeter Avalos 49618de8d7fSPeter Avalos case oTCPKeepAlive: 49718de8d7fSPeter Avalos intptr = &options->tcp_keep_alive; 49818de8d7fSPeter Avalos goto parse_flag; 49918de8d7fSPeter Avalos 50018de8d7fSPeter Avalos case oNoHostAuthenticationForLocalhost: 50118de8d7fSPeter Avalos intptr = &options->no_host_authentication_for_localhost; 50218de8d7fSPeter Avalos goto parse_flag; 50318de8d7fSPeter Avalos 50418de8d7fSPeter Avalos case oNumberOfPasswordPrompts: 50518de8d7fSPeter Avalos intptr = &options->number_of_password_prompts; 50618de8d7fSPeter Avalos goto parse_int; 50718de8d7fSPeter Avalos 50818de8d7fSPeter Avalos case oCompressionLevel: 50918de8d7fSPeter Avalos intptr = &options->compression_level; 51018de8d7fSPeter Avalos goto parse_int; 51118de8d7fSPeter Avalos 51218de8d7fSPeter Avalos case oRekeyLimit: 51318de8d7fSPeter Avalos arg = strdelim(&s); 51418de8d7fSPeter Avalos if (!arg || *arg == '\0') 51518de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 51618de8d7fSPeter Avalos if (arg[0] < '0' || arg[0] > '9') 51718de8d7fSPeter Avalos fatal("%.200s line %d: Bad number.", filename, linenum); 51818de8d7fSPeter Avalos orig = val64 = strtoll(arg, &endofnumber, 10); 51918de8d7fSPeter Avalos if (arg == endofnumber) 52018de8d7fSPeter Avalos fatal("%.200s line %d: Bad number.", filename, linenum); 52118de8d7fSPeter Avalos switch (toupper(*endofnumber)) { 52218de8d7fSPeter Avalos case '\0': 52318de8d7fSPeter Avalos scale = 1; 52418de8d7fSPeter Avalos break; 52518de8d7fSPeter Avalos case 'K': 52618de8d7fSPeter Avalos scale = 1<<10; 52718de8d7fSPeter Avalos break; 52818de8d7fSPeter Avalos case 'M': 52918de8d7fSPeter Avalos scale = 1<<20; 53018de8d7fSPeter Avalos break; 53118de8d7fSPeter Avalos case 'G': 53218de8d7fSPeter Avalos scale = 1<<30; 53318de8d7fSPeter Avalos break; 53418de8d7fSPeter Avalos default: 53518de8d7fSPeter Avalos fatal("%.200s line %d: Invalid RekeyLimit suffix", 53618de8d7fSPeter Avalos filename, linenum); 53718de8d7fSPeter Avalos } 53818de8d7fSPeter Avalos val64 *= scale; 53918de8d7fSPeter Avalos /* detect integer wrap and too-large limits */ 54018de8d7fSPeter Avalos if ((val64 / scale) != orig || val64 > UINT_MAX) 54118de8d7fSPeter Avalos fatal("%.200s line %d: RekeyLimit too large", 54218de8d7fSPeter Avalos filename, linenum); 54318de8d7fSPeter Avalos if (val64 < 16) 54418de8d7fSPeter Avalos fatal("%.200s line %d: RekeyLimit too small", 54518de8d7fSPeter Avalos filename, linenum); 54618de8d7fSPeter Avalos if (*activep && options->rekey_limit == -1) 54718de8d7fSPeter Avalos options->rekey_limit = (u_int32_t)val64; 54818de8d7fSPeter Avalos break; 54918de8d7fSPeter Avalos 55018de8d7fSPeter Avalos case oIdentityFile: 55118de8d7fSPeter Avalos arg = strdelim(&s); 55218de8d7fSPeter Avalos if (!arg || *arg == '\0') 55318de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 55418de8d7fSPeter Avalos if (*activep) { 55518de8d7fSPeter Avalos intptr = &options->num_identity_files; 55618de8d7fSPeter Avalos if (*intptr >= SSH_MAX_IDENTITY_FILES) 55718de8d7fSPeter Avalos fatal("%.200s line %d: Too many identity files specified (max %d).", 55818de8d7fSPeter Avalos filename, linenum, SSH_MAX_IDENTITY_FILES); 55918de8d7fSPeter Avalos charptr = &options->identity_files[*intptr]; 56018de8d7fSPeter Avalos *charptr = xstrdup(arg); 56118de8d7fSPeter Avalos *intptr = *intptr + 1; 56218de8d7fSPeter Avalos } 56318de8d7fSPeter Avalos break; 56418de8d7fSPeter Avalos 56518de8d7fSPeter Avalos case oXAuthLocation: 56618de8d7fSPeter Avalos charptr=&options->xauth_location; 56718de8d7fSPeter Avalos goto parse_string; 56818de8d7fSPeter Avalos 56918de8d7fSPeter Avalos case oUser: 57018de8d7fSPeter Avalos charptr = &options->user; 57118de8d7fSPeter Avalos parse_string: 57218de8d7fSPeter Avalos arg = strdelim(&s); 57318de8d7fSPeter Avalos if (!arg || *arg == '\0') 57418de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 57518de8d7fSPeter Avalos if (*activep && *charptr == NULL) 57618de8d7fSPeter Avalos *charptr = xstrdup(arg); 57718de8d7fSPeter Avalos break; 57818de8d7fSPeter Avalos 57918de8d7fSPeter Avalos case oGlobalKnownHostsFile: 58018de8d7fSPeter Avalos charptr = &options->system_hostfile; 58118de8d7fSPeter Avalos goto parse_string; 58218de8d7fSPeter Avalos 58318de8d7fSPeter Avalos case oUserKnownHostsFile: 58418de8d7fSPeter Avalos charptr = &options->user_hostfile; 58518de8d7fSPeter Avalos goto parse_string; 58618de8d7fSPeter Avalos 58718de8d7fSPeter Avalos case oGlobalKnownHostsFile2: 58818de8d7fSPeter Avalos charptr = &options->system_hostfile2; 58918de8d7fSPeter Avalos goto parse_string; 59018de8d7fSPeter Avalos 59118de8d7fSPeter Avalos case oUserKnownHostsFile2: 59218de8d7fSPeter Avalos charptr = &options->user_hostfile2; 59318de8d7fSPeter Avalos goto parse_string; 59418de8d7fSPeter Avalos 59518de8d7fSPeter Avalos case oHostName: 59618de8d7fSPeter Avalos charptr = &options->hostname; 59718de8d7fSPeter Avalos goto parse_string; 59818de8d7fSPeter Avalos 59918de8d7fSPeter Avalos case oHostKeyAlias: 60018de8d7fSPeter Avalos charptr = &options->host_key_alias; 60118de8d7fSPeter Avalos goto parse_string; 60218de8d7fSPeter Avalos 60318de8d7fSPeter Avalos case oPreferredAuthentications: 60418de8d7fSPeter Avalos charptr = &options->preferred_authentications; 60518de8d7fSPeter Avalos goto parse_string; 60618de8d7fSPeter Avalos 60718de8d7fSPeter Avalos case oBindAddress: 60818de8d7fSPeter Avalos charptr = &options->bind_address; 60918de8d7fSPeter Avalos goto parse_string; 61018de8d7fSPeter Avalos 61118de8d7fSPeter Avalos case oSmartcardDevice: 61218de8d7fSPeter Avalos charptr = &options->smartcard_device; 61318de8d7fSPeter Avalos goto parse_string; 61418de8d7fSPeter Avalos 61518de8d7fSPeter Avalos case oProxyCommand: 61618de8d7fSPeter Avalos charptr = &options->proxy_command; 61718de8d7fSPeter Avalos parse_command: 61818de8d7fSPeter Avalos if (s == NULL) 61918de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 62018de8d7fSPeter Avalos len = strspn(s, WHITESPACE "="); 62118de8d7fSPeter Avalos if (*activep && *charptr == NULL) 62218de8d7fSPeter Avalos *charptr = xstrdup(s + len); 62318de8d7fSPeter Avalos return 0; 62418de8d7fSPeter Avalos 62518de8d7fSPeter Avalos case oPort: 62618de8d7fSPeter Avalos intptr = &options->port; 62718de8d7fSPeter Avalos parse_int: 62818de8d7fSPeter Avalos arg = strdelim(&s); 62918de8d7fSPeter Avalos if (!arg || *arg == '\0') 63018de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 63118de8d7fSPeter Avalos if (arg[0] < '0' || arg[0] > '9') 63218de8d7fSPeter Avalos fatal("%.200s line %d: Bad number.", filename, linenum); 63318de8d7fSPeter Avalos 63418de8d7fSPeter Avalos /* Octal, decimal, or hex format? */ 63518de8d7fSPeter Avalos value = strtol(arg, &endofnumber, 0); 63618de8d7fSPeter Avalos if (arg == endofnumber) 63718de8d7fSPeter Avalos fatal("%.200s line %d: Bad number.", filename, linenum); 63818de8d7fSPeter Avalos if (*activep && *intptr == -1) 63918de8d7fSPeter Avalos *intptr = value; 64018de8d7fSPeter Avalos break; 64118de8d7fSPeter Avalos 64218de8d7fSPeter Avalos case oConnectionAttempts: 64318de8d7fSPeter Avalos intptr = &options->connection_attempts; 64418de8d7fSPeter Avalos goto parse_int; 64518de8d7fSPeter Avalos 64618de8d7fSPeter Avalos case oCipher: 64718de8d7fSPeter Avalos intptr = &options->cipher; 64818de8d7fSPeter Avalos arg = strdelim(&s); 64918de8d7fSPeter Avalos if (!arg || *arg == '\0') 65018de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 65118de8d7fSPeter Avalos value = cipher_number(arg); 65218de8d7fSPeter Avalos if (value == -1) 65318de8d7fSPeter Avalos fatal("%.200s line %d: Bad cipher '%s'.", 65418de8d7fSPeter Avalos filename, linenum, arg ? arg : "<NONE>"); 65518de8d7fSPeter Avalos if (*activep && *intptr == -1) 65618de8d7fSPeter Avalos *intptr = value; 65718de8d7fSPeter Avalos break; 65818de8d7fSPeter Avalos 65918de8d7fSPeter Avalos case oCiphers: 66018de8d7fSPeter Avalos arg = strdelim(&s); 66118de8d7fSPeter Avalos if (!arg || *arg == '\0') 66218de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 66318de8d7fSPeter Avalos if (!ciphers_valid(arg)) 66418de8d7fSPeter Avalos fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 66518de8d7fSPeter Avalos filename, linenum, arg ? arg : "<NONE>"); 66618de8d7fSPeter Avalos if (*activep && options->ciphers == NULL) 66718de8d7fSPeter Avalos options->ciphers = xstrdup(arg); 66818de8d7fSPeter Avalos break; 66918de8d7fSPeter Avalos 67018de8d7fSPeter Avalos case oMacs: 67118de8d7fSPeter Avalos arg = strdelim(&s); 67218de8d7fSPeter Avalos if (!arg || *arg == '\0') 67318de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 67418de8d7fSPeter Avalos if (!mac_valid(arg)) 67518de8d7fSPeter Avalos fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 67618de8d7fSPeter Avalos filename, linenum, arg ? arg : "<NONE>"); 67718de8d7fSPeter Avalos if (*activep && options->macs == NULL) 67818de8d7fSPeter Avalos options->macs = xstrdup(arg); 67918de8d7fSPeter Avalos break; 68018de8d7fSPeter Avalos 68118de8d7fSPeter Avalos case oHostKeyAlgorithms: 68218de8d7fSPeter Avalos arg = strdelim(&s); 68318de8d7fSPeter Avalos if (!arg || *arg == '\0') 68418de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 68518de8d7fSPeter Avalos if (!key_names_valid2(arg)) 68618de8d7fSPeter Avalos fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 68718de8d7fSPeter Avalos filename, linenum, arg ? arg : "<NONE>"); 68818de8d7fSPeter Avalos if (*activep && options->hostkeyalgorithms == NULL) 68918de8d7fSPeter Avalos options->hostkeyalgorithms = xstrdup(arg); 69018de8d7fSPeter Avalos break; 69118de8d7fSPeter Avalos 69218de8d7fSPeter Avalos case oProtocol: 69318de8d7fSPeter Avalos intptr = &options->protocol; 69418de8d7fSPeter Avalos arg = strdelim(&s); 69518de8d7fSPeter Avalos if (!arg || *arg == '\0') 69618de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 69718de8d7fSPeter Avalos value = proto_spec(arg); 69818de8d7fSPeter Avalos if (value == SSH_PROTO_UNKNOWN) 69918de8d7fSPeter Avalos fatal("%.200s line %d: Bad protocol spec '%s'.", 70018de8d7fSPeter Avalos filename, linenum, arg ? arg : "<NONE>"); 70118de8d7fSPeter Avalos if (*activep && *intptr == SSH_PROTO_UNKNOWN) 70218de8d7fSPeter Avalos *intptr = value; 70318de8d7fSPeter Avalos break; 70418de8d7fSPeter Avalos 70518de8d7fSPeter Avalos case oLogLevel: 70618de8d7fSPeter Avalos log_level_ptr = &options->log_level; 70718de8d7fSPeter Avalos arg = strdelim(&s); 70818de8d7fSPeter Avalos value = log_level_number(arg); 70918de8d7fSPeter Avalos if (value == SYSLOG_LEVEL_NOT_SET) 71018de8d7fSPeter Avalos fatal("%.200s line %d: unsupported log level '%s'", 71118de8d7fSPeter Avalos filename, linenum, arg ? arg : "<NONE>"); 71218de8d7fSPeter Avalos if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 71318de8d7fSPeter Avalos *log_level_ptr = (LogLevel) value; 71418de8d7fSPeter Avalos break; 71518de8d7fSPeter Avalos 71618de8d7fSPeter Avalos case oLocalForward: 71718de8d7fSPeter Avalos case oRemoteForward: 718*cb5eb4f1SPeter Avalos case oDynamicForward: 71918de8d7fSPeter Avalos arg = strdelim(&s); 72018de8d7fSPeter Avalos if (arg == NULL || *arg == '\0') 72118de8d7fSPeter Avalos fatal("%.200s line %d: Missing port argument.", 72218de8d7fSPeter Avalos filename, linenum); 723*cb5eb4f1SPeter Avalos 724*cb5eb4f1SPeter Avalos if (opcode == oLocalForward || 725*cb5eb4f1SPeter Avalos opcode == oRemoteForward) { 72618de8d7fSPeter Avalos arg2 = strdelim(&s); 72718de8d7fSPeter Avalos if (arg2 == NULL || *arg2 == '\0') 72818de8d7fSPeter Avalos fatal("%.200s line %d: Missing target argument.", 72918de8d7fSPeter Avalos filename, linenum); 73018de8d7fSPeter Avalos 73118de8d7fSPeter Avalos /* construct a string for parse_forward */ 73218de8d7fSPeter Avalos snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 733*cb5eb4f1SPeter Avalos } else if (opcode == oDynamicForward) { 734*cb5eb4f1SPeter Avalos strlcpy(fwdarg, arg, sizeof(fwdarg)); 735*cb5eb4f1SPeter Avalos } 73618de8d7fSPeter Avalos 737*cb5eb4f1SPeter Avalos if (parse_forward(&fwd, fwdarg, 738*cb5eb4f1SPeter Avalos opcode == oDynamicForward ? 1 : 0, 739*cb5eb4f1SPeter Avalos opcode == oRemoteForward ? 1 : 0) == 0) 74018de8d7fSPeter Avalos fatal("%.200s line %d: Bad forwarding specification.", 74118de8d7fSPeter Avalos filename, linenum); 74218de8d7fSPeter Avalos 74318de8d7fSPeter Avalos if (*activep) { 744*cb5eb4f1SPeter Avalos if (opcode == oLocalForward || 745*cb5eb4f1SPeter Avalos opcode == oDynamicForward) 74618de8d7fSPeter Avalos add_local_forward(options, &fwd); 74718de8d7fSPeter Avalos else if (opcode == oRemoteForward) 74818de8d7fSPeter Avalos add_remote_forward(options, &fwd); 74918de8d7fSPeter Avalos } 75018de8d7fSPeter Avalos break; 75118de8d7fSPeter Avalos 75218de8d7fSPeter Avalos case oClearAllForwardings: 75318de8d7fSPeter Avalos intptr = &options->clear_forwardings; 75418de8d7fSPeter Avalos goto parse_flag; 75518de8d7fSPeter Avalos 75618de8d7fSPeter Avalos case oHost: 75718de8d7fSPeter Avalos *activep = 0; 75818de8d7fSPeter Avalos while ((arg = strdelim(&s)) != NULL && *arg != '\0') 75918de8d7fSPeter Avalos if (match_pattern(host, arg)) { 76018de8d7fSPeter Avalos debug("Applying options for %.100s", arg); 76118de8d7fSPeter Avalos *activep = 1; 76218de8d7fSPeter Avalos break; 76318de8d7fSPeter Avalos } 76418de8d7fSPeter Avalos /* Avoid garbage check below, as strdelim is done. */ 76518de8d7fSPeter Avalos return 0; 76618de8d7fSPeter Avalos 76718de8d7fSPeter Avalos case oEscapeChar: 76818de8d7fSPeter Avalos intptr = &options->escape_char; 76918de8d7fSPeter Avalos arg = strdelim(&s); 77018de8d7fSPeter Avalos if (!arg || *arg == '\0') 77118de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 77218de8d7fSPeter Avalos if (arg[0] == '^' && arg[2] == 0 && 77318de8d7fSPeter Avalos (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 77418de8d7fSPeter Avalos value = (u_char) arg[1] & 31; 77518de8d7fSPeter Avalos else if (strlen(arg) == 1) 77618de8d7fSPeter Avalos value = (u_char) arg[0]; 77718de8d7fSPeter Avalos else if (strcmp(arg, "none") == 0) 77818de8d7fSPeter Avalos value = SSH_ESCAPECHAR_NONE; 77918de8d7fSPeter Avalos else { 78018de8d7fSPeter Avalos fatal("%.200s line %d: Bad escape character.", 78118de8d7fSPeter Avalos filename, linenum); 78218de8d7fSPeter Avalos /* NOTREACHED */ 78318de8d7fSPeter Avalos value = 0; /* Avoid compiler warning. */ 78418de8d7fSPeter Avalos } 78518de8d7fSPeter Avalos if (*activep && *intptr == -1) 78618de8d7fSPeter Avalos *intptr = value; 78718de8d7fSPeter Avalos break; 78818de8d7fSPeter Avalos 78918de8d7fSPeter Avalos case oAddressFamily: 79018de8d7fSPeter Avalos arg = strdelim(&s); 79118de8d7fSPeter Avalos if (!arg || *arg == '\0') 79218de8d7fSPeter Avalos fatal("%s line %d: missing address family.", 79318de8d7fSPeter Avalos filename, linenum); 79418de8d7fSPeter Avalos intptr = &options->address_family; 79518de8d7fSPeter Avalos if (strcasecmp(arg, "inet") == 0) 79618de8d7fSPeter Avalos value = AF_INET; 79718de8d7fSPeter Avalos else if (strcasecmp(arg, "inet6") == 0) 79818de8d7fSPeter Avalos value = AF_INET6; 79918de8d7fSPeter Avalos else if (strcasecmp(arg, "any") == 0) 80018de8d7fSPeter Avalos value = AF_UNSPEC; 80118de8d7fSPeter Avalos else 80218de8d7fSPeter Avalos fatal("Unsupported AddressFamily \"%s\"", arg); 80318de8d7fSPeter Avalos if (*activep && *intptr == -1) 80418de8d7fSPeter Avalos *intptr = value; 80518de8d7fSPeter Avalos break; 80618de8d7fSPeter Avalos 80718de8d7fSPeter Avalos case oEnableSSHKeysign: 80818de8d7fSPeter Avalos intptr = &options->enable_ssh_keysign; 80918de8d7fSPeter Avalos goto parse_flag; 81018de8d7fSPeter Avalos 81118de8d7fSPeter Avalos case oIdentitiesOnly: 81218de8d7fSPeter Avalos intptr = &options->identities_only; 81318de8d7fSPeter Avalos goto parse_flag; 81418de8d7fSPeter Avalos 81518de8d7fSPeter Avalos case oServerAliveInterval: 81618de8d7fSPeter Avalos intptr = &options->server_alive_interval; 81718de8d7fSPeter Avalos goto parse_time; 81818de8d7fSPeter Avalos 81918de8d7fSPeter Avalos case oServerAliveCountMax: 82018de8d7fSPeter Avalos intptr = &options->server_alive_count_max; 82118de8d7fSPeter Avalos goto parse_int; 82218de8d7fSPeter Avalos 82318de8d7fSPeter Avalos case oSendEnv: 82418de8d7fSPeter Avalos while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 82518de8d7fSPeter Avalos if (strchr(arg, '=') != NULL) 82618de8d7fSPeter Avalos fatal("%s line %d: Invalid environment name.", 82718de8d7fSPeter Avalos filename, linenum); 82818de8d7fSPeter Avalos if (!*activep) 82918de8d7fSPeter Avalos continue; 83018de8d7fSPeter Avalos if (options->num_send_env >= MAX_SEND_ENV) 83118de8d7fSPeter Avalos fatal("%s line %d: too many send env.", 83218de8d7fSPeter Avalos filename, linenum); 83318de8d7fSPeter Avalos options->send_env[options->num_send_env++] = 83418de8d7fSPeter Avalos xstrdup(arg); 83518de8d7fSPeter Avalos } 83618de8d7fSPeter Avalos break; 83718de8d7fSPeter Avalos 83818de8d7fSPeter Avalos case oControlPath: 83918de8d7fSPeter Avalos charptr = &options->control_path; 84018de8d7fSPeter Avalos goto parse_string; 84118de8d7fSPeter Avalos 84218de8d7fSPeter Avalos case oControlMaster: 84318de8d7fSPeter Avalos intptr = &options->control_master; 84418de8d7fSPeter Avalos arg = strdelim(&s); 84518de8d7fSPeter Avalos if (!arg || *arg == '\0') 84618de8d7fSPeter Avalos fatal("%.200s line %d: Missing ControlMaster argument.", 84718de8d7fSPeter Avalos filename, linenum); 84818de8d7fSPeter Avalos value = 0; /* To avoid compiler warning... */ 84918de8d7fSPeter Avalos if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 85018de8d7fSPeter Avalos value = SSHCTL_MASTER_YES; 85118de8d7fSPeter Avalos else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 85218de8d7fSPeter Avalos value = SSHCTL_MASTER_NO; 85318de8d7fSPeter Avalos else if (strcmp(arg, "auto") == 0) 85418de8d7fSPeter Avalos value = SSHCTL_MASTER_AUTO; 85518de8d7fSPeter Avalos else if (strcmp(arg, "ask") == 0) 85618de8d7fSPeter Avalos value = SSHCTL_MASTER_ASK; 85718de8d7fSPeter Avalos else if (strcmp(arg, "autoask") == 0) 85818de8d7fSPeter Avalos value = SSHCTL_MASTER_AUTO_ASK; 85918de8d7fSPeter Avalos else 86018de8d7fSPeter Avalos fatal("%.200s line %d: Bad ControlMaster argument.", 86118de8d7fSPeter Avalos filename, linenum); 86218de8d7fSPeter Avalos if (*activep && *intptr == -1) 86318de8d7fSPeter Avalos *intptr = value; 86418de8d7fSPeter Avalos break; 86518de8d7fSPeter Avalos 86618de8d7fSPeter Avalos case oHashKnownHosts: 86718de8d7fSPeter Avalos intptr = &options->hash_known_hosts; 86818de8d7fSPeter Avalos goto parse_flag; 86918de8d7fSPeter Avalos 87018de8d7fSPeter Avalos case oTunnel: 87118de8d7fSPeter Avalos intptr = &options->tun_open; 87218de8d7fSPeter Avalos arg = strdelim(&s); 87318de8d7fSPeter Avalos if (!arg || *arg == '\0') 87418de8d7fSPeter Avalos fatal("%s line %d: Missing yes/point-to-point/" 87518de8d7fSPeter Avalos "ethernet/no argument.", filename, linenum); 87618de8d7fSPeter Avalos value = 0; /* silence compiler */ 87718de8d7fSPeter Avalos if (strcasecmp(arg, "ethernet") == 0) 87818de8d7fSPeter Avalos value = SSH_TUNMODE_ETHERNET; 87918de8d7fSPeter Avalos else if (strcasecmp(arg, "point-to-point") == 0) 88018de8d7fSPeter Avalos value = SSH_TUNMODE_POINTOPOINT; 88118de8d7fSPeter Avalos else if (strcasecmp(arg, "yes") == 0) 88218de8d7fSPeter Avalos value = SSH_TUNMODE_DEFAULT; 88318de8d7fSPeter Avalos else if (strcasecmp(arg, "no") == 0) 88418de8d7fSPeter Avalos value = SSH_TUNMODE_NO; 88518de8d7fSPeter Avalos else 88618de8d7fSPeter Avalos fatal("%s line %d: Bad yes/point-to-point/ethernet/" 88718de8d7fSPeter Avalos "no argument: %s", filename, linenum, arg); 88818de8d7fSPeter Avalos if (*activep) 88918de8d7fSPeter Avalos *intptr = value; 89018de8d7fSPeter Avalos break; 89118de8d7fSPeter Avalos 89218de8d7fSPeter Avalos case oTunnelDevice: 89318de8d7fSPeter Avalos arg = strdelim(&s); 89418de8d7fSPeter Avalos if (!arg || *arg == '\0') 89518de8d7fSPeter Avalos fatal("%.200s line %d: Missing argument.", filename, linenum); 89618de8d7fSPeter Avalos value = a2tun(arg, &value2); 89718de8d7fSPeter Avalos if (value == SSH_TUNID_ERR) 89818de8d7fSPeter Avalos fatal("%.200s line %d: Bad tun device.", filename, linenum); 89918de8d7fSPeter Avalos if (*activep) { 90018de8d7fSPeter Avalos options->tun_local = value; 90118de8d7fSPeter Avalos options->tun_remote = value2; 90218de8d7fSPeter Avalos } 90318de8d7fSPeter Avalos break; 90418de8d7fSPeter Avalos 90518de8d7fSPeter Avalos case oLocalCommand: 90618de8d7fSPeter Avalos charptr = &options->local_command; 90718de8d7fSPeter Avalos goto parse_command; 90818de8d7fSPeter Avalos 90918de8d7fSPeter Avalos case oPermitLocalCommand: 91018de8d7fSPeter Avalos intptr = &options->permit_local_command; 91118de8d7fSPeter Avalos goto parse_flag; 91218de8d7fSPeter Avalos 91318de8d7fSPeter Avalos case oVisualHostKey: 91418de8d7fSPeter Avalos intptr = &options->visual_host_key; 91518de8d7fSPeter Avalos goto parse_flag; 91618de8d7fSPeter Avalos 91718de8d7fSPeter Avalos case oDeprecated: 91818de8d7fSPeter Avalos debug("%s line %d: Deprecated option \"%s\"", 91918de8d7fSPeter Avalos filename, linenum, keyword); 92018de8d7fSPeter Avalos return 0; 92118de8d7fSPeter Avalos 92218de8d7fSPeter Avalos case oUnsupported: 92318de8d7fSPeter Avalos error("%s line %d: Unsupported option \"%s\"", 92418de8d7fSPeter Avalos filename, linenum, keyword); 92518de8d7fSPeter Avalos return 0; 92618de8d7fSPeter Avalos 92718de8d7fSPeter Avalos default: 92818de8d7fSPeter Avalos fatal("process_config_line: Unimplemented opcode %d", opcode); 92918de8d7fSPeter Avalos } 93018de8d7fSPeter Avalos 93118de8d7fSPeter Avalos /* Check that there is no garbage at end of line. */ 93218de8d7fSPeter Avalos if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 93318de8d7fSPeter Avalos fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 93418de8d7fSPeter Avalos filename, linenum, arg); 93518de8d7fSPeter Avalos } 93618de8d7fSPeter Avalos return 0; 93718de8d7fSPeter Avalos } 93818de8d7fSPeter Avalos 93918de8d7fSPeter Avalos 94018de8d7fSPeter Avalos /* 94118de8d7fSPeter Avalos * Reads the config file and modifies the options accordingly. Options 94218de8d7fSPeter Avalos * should already be initialized before this call. This never returns if 94318de8d7fSPeter Avalos * there is an error. If the file does not exist, this returns 0. 94418de8d7fSPeter Avalos */ 94518de8d7fSPeter Avalos 94618de8d7fSPeter Avalos int 94718de8d7fSPeter Avalos read_config_file(const char *filename, const char *host, Options *options, 94818de8d7fSPeter Avalos int checkperm) 94918de8d7fSPeter Avalos { 95018de8d7fSPeter Avalos FILE *f; 95118de8d7fSPeter Avalos char line[1024]; 95218de8d7fSPeter Avalos int active, linenum; 95318de8d7fSPeter Avalos int bad_options = 0; 95418de8d7fSPeter Avalos 95518de8d7fSPeter Avalos if ((f = fopen(filename, "r")) == NULL) 95618de8d7fSPeter Avalos return 0; 95718de8d7fSPeter Avalos 95818de8d7fSPeter Avalos if (checkperm) { 95918de8d7fSPeter Avalos struct stat sb; 96018de8d7fSPeter Avalos 96118de8d7fSPeter Avalos if (fstat(fileno(f), &sb) == -1) 96218de8d7fSPeter Avalos fatal("fstat %s: %s", filename, strerror(errno)); 96318de8d7fSPeter Avalos if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 96418de8d7fSPeter Avalos (sb.st_mode & 022) != 0)) 96518de8d7fSPeter Avalos fatal("Bad owner or permissions on %s", filename); 96618de8d7fSPeter Avalos } 96718de8d7fSPeter Avalos 96818de8d7fSPeter Avalos debug("Reading configuration data %.200s", filename); 96918de8d7fSPeter Avalos 97018de8d7fSPeter Avalos /* 97118de8d7fSPeter Avalos * Mark that we are now processing the options. This flag is turned 97218de8d7fSPeter Avalos * on/off by Host specifications. 97318de8d7fSPeter Avalos */ 97418de8d7fSPeter Avalos active = 1; 97518de8d7fSPeter Avalos linenum = 0; 97618de8d7fSPeter Avalos while (fgets(line, sizeof(line), f)) { 97718de8d7fSPeter Avalos /* Update line number counter. */ 97818de8d7fSPeter Avalos linenum++; 97918de8d7fSPeter Avalos if (process_config_line(options, host, line, filename, linenum, &active) != 0) 98018de8d7fSPeter Avalos bad_options++; 98118de8d7fSPeter Avalos } 98218de8d7fSPeter Avalos fclose(f); 98318de8d7fSPeter Avalos if (bad_options > 0) 98418de8d7fSPeter Avalos fatal("%s: terminating, %d bad configuration options", 98518de8d7fSPeter Avalos filename, bad_options); 98618de8d7fSPeter Avalos return 1; 98718de8d7fSPeter Avalos } 98818de8d7fSPeter Avalos 98918de8d7fSPeter Avalos /* 99018de8d7fSPeter Avalos * Initializes options to special values that indicate that they have not yet 99118de8d7fSPeter Avalos * been set. Read_config_file will only set options with this value. Options 99218de8d7fSPeter Avalos * are processed in the following order: command line, user config file, 99318de8d7fSPeter Avalos * system config file. Last, fill_default_options is called. 99418de8d7fSPeter Avalos */ 99518de8d7fSPeter Avalos 99618de8d7fSPeter Avalos void 99718de8d7fSPeter Avalos initialize_options(Options * options) 99818de8d7fSPeter Avalos { 99918de8d7fSPeter Avalos memset(options, 'X', sizeof(*options)); 100018de8d7fSPeter Avalos options->forward_agent = -1; 100118de8d7fSPeter Avalos options->forward_x11 = -1; 100218de8d7fSPeter Avalos options->forward_x11_trusted = -1; 100318de8d7fSPeter Avalos options->exit_on_forward_failure = -1; 100418de8d7fSPeter Avalos options->xauth_location = NULL; 100518de8d7fSPeter Avalos options->gateway_ports = -1; 100618de8d7fSPeter Avalos options->use_privileged_port = -1; 100718de8d7fSPeter Avalos options->rsa_authentication = -1; 100818de8d7fSPeter Avalos options->pubkey_authentication = -1; 100918de8d7fSPeter Avalos options->challenge_response_authentication = -1; 101018de8d7fSPeter Avalos options->gss_authentication = -1; 101118de8d7fSPeter Avalos options->gss_deleg_creds = -1; 101218de8d7fSPeter Avalos options->password_authentication = -1; 101318de8d7fSPeter Avalos options->kbd_interactive_authentication = -1; 101418de8d7fSPeter Avalos options->kbd_interactive_devices = NULL; 101518de8d7fSPeter Avalos options->rhosts_rsa_authentication = -1; 101618de8d7fSPeter Avalos options->hostbased_authentication = -1; 101718de8d7fSPeter Avalos options->batch_mode = -1; 101818de8d7fSPeter Avalos options->check_host_ip = -1; 101918de8d7fSPeter Avalos options->strict_host_key_checking = -1; 102018de8d7fSPeter Avalos options->compression = -1; 102118de8d7fSPeter Avalos options->tcp_keep_alive = -1; 102218de8d7fSPeter Avalos options->compression_level = -1; 102318de8d7fSPeter Avalos options->port = -1; 102418de8d7fSPeter Avalos options->address_family = -1; 102518de8d7fSPeter Avalos options->connection_attempts = -1; 102618de8d7fSPeter Avalos options->connection_timeout = -1; 102718de8d7fSPeter Avalos options->number_of_password_prompts = -1; 102818de8d7fSPeter Avalos options->cipher = -1; 102918de8d7fSPeter Avalos options->ciphers = NULL; 103018de8d7fSPeter Avalos options->macs = NULL; 103118de8d7fSPeter Avalos options->hostkeyalgorithms = NULL; 103218de8d7fSPeter Avalos options->protocol = SSH_PROTO_UNKNOWN; 103318de8d7fSPeter Avalos options->num_identity_files = 0; 103418de8d7fSPeter Avalos options->hostname = NULL; 103518de8d7fSPeter Avalos options->host_key_alias = NULL; 103618de8d7fSPeter Avalos options->proxy_command = NULL; 103718de8d7fSPeter Avalos options->user = NULL; 103818de8d7fSPeter Avalos options->escape_char = -1; 103918de8d7fSPeter Avalos options->system_hostfile = NULL; 104018de8d7fSPeter Avalos options->user_hostfile = NULL; 104118de8d7fSPeter Avalos options->system_hostfile2 = NULL; 104218de8d7fSPeter Avalos options->user_hostfile2 = NULL; 104318de8d7fSPeter Avalos options->num_local_forwards = 0; 104418de8d7fSPeter Avalos options->num_remote_forwards = 0; 104518de8d7fSPeter Avalos options->clear_forwardings = -1; 104618de8d7fSPeter Avalos options->log_level = SYSLOG_LEVEL_NOT_SET; 104718de8d7fSPeter Avalos options->preferred_authentications = NULL; 104818de8d7fSPeter Avalos options->bind_address = NULL; 104918de8d7fSPeter Avalos options->smartcard_device = NULL; 105018de8d7fSPeter Avalos options->enable_ssh_keysign = - 1; 105118de8d7fSPeter Avalos options->no_host_authentication_for_localhost = - 1; 105218de8d7fSPeter Avalos options->identities_only = - 1; 105318de8d7fSPeter Avalos options->rekey_limit = - 1; 105418de8d7fSPeter Avalos options->verify_host_key_dns = -1; 105518de8d7fSPeter Avalos options->server_alive_interval = -1; 105618de8d7fSPeter Avalos options->server_alive_count_max = -1; 105718de8d7fSPeter Avalos options->num_send_env = 0; 105818de8d7fSPeter Avalos options->control_path = NULL; 105918de8d7fSPeter Avalos options->control_master = -1; 106018de8d7fSPeter Avalos options->hash_known_hosts = -1; 106118de8d7fSPeter Avalos options->tun_open = -1; 106218de8d7fSPeter Avalos options->tun_local = -1; 106318de8d7fSPeter Avalos options->tun_remote = -1; 106418de8d7fSPeter Avalos options->local_command = NULL; 106518de8d7fSPeter Avalos options->permit_local_command = -1; 106618de8d7fSPeter Avalos options->visual_host_key = -1; 1067*cb5eb4f1SPeter Avalos options->zero_knowledge_password_authentication = -1; 106818de8d7fSPeter Avalos } 106918de8d7fSPeter Avalos 107018de8d7fSPeter Avalos /* 107118de8d7fSPeter Avalos * Called after processing other sources of option data, this fills those 107218de8d7fSPeter Avalos * options for which no value has been specified with their default values. 107318de8d7fSPeter Avalos */ 107418de8d7fSPeter Avalos 107518de8d7fSPeter Avalos void 107618de8d7fSPeter Avalos fill_default_options(Options * options) 107718de8d7fSPeter Avalos { 107818de8d7fSPeter Avalos int len; 107918de8d7fSPeter Avalos 108018de8d7fSPeter Avalos if (options->forward_agent == -1) 108118de8d7fSPeter Avalos options->forward_agent = 0; 108218de8d7fSPeter Avalos if (options->forward_x11 == -1) 108318de8d7fSPeter Avalos options->forward_x11 = 0; 108418de8d7fSPeter Avalos if (options->forward_x11_trusted == -1) 108518de8d7fSPeter Avalos options->forward_x11_trusted = 0; 108618de8d7fSPeter Avalos if (options->exit_on_forward_failure == -1) 108718de8d7fSPeter Avalos options->exit_on_forward_failure = 0; 108818de8d7fSPeter Avalos if (options->xauth_location == NULL) 108918de8d7fSPeter Avalos options->xauth_location = _PATH_XAUTH; 109018de8d7fSPeter Avalos if (options->gateway_ports == -1) 109118de8d7fSPeter Avalos options->gateway_ports = 0; 109218de8d7fSPeter Avalos if (options->use_privileged_port == -1) 109318de8d7fSPeter Avalos options->use_privileged_port = 0; 109418de8d7fSPeter Avalos if (options->rsa_authentication == -1) 109518de8d7fSPeter Avalos options->rsa_authentication = 1; 109618de8d7fSPeter Avalos if (options->pubkey_authentication == -1) 109718de8d7fSPeter Avalos options->pubkey_authentication = 1; 109818de8d7fSPeter Avalos if (options->challenge_response_authentication == -1) 109918de8d7fSPeter Avalos options->challenge_response_authentication = 1; 110018de8d7fSPeter Avalos if (options->gss_authentication == -1) 110118de8d7fSPeter Avalos options->gss_authentication = 0; 110218de8d7fSPeter Avalos if (options->gss_deleg_creds == -1) 110318de8d7fSPeter Avalos options->gss_deleg_creds = 0; 110418de8d7fSPeter Avalos if (options->password_authentication == -1) 110518de8d7fSPeter Avalos options->password_authentication = 1; 110618de8d7fSPeter Avalos if (options->kbd_interactive_authentication == -1) 110718de8d7fSPeter Avalos options->kbd_interactive_authentication = 1; 110818de8d7fSPeter Avalos if (options->rhosts_rsa_authentication == -1) 110918de8d7fSPeter Avalos options->rhosts_rsa_authentication = 0; 111018de8d7fSPeter Avalos if (options->hostbased_authentication == -1) 111118de8d7fSPeter Avalos options->hostbased_authentication = 0; 111218de8d7fSPeter Avalos if (options->batch_mode == -1) 111318de8d7fSPeter Avalos options->batch_mode = 0; 111418de8d7fSPeter Avalos if (options->check_host_ip == -1) 111518de8d7fSPeter Avalos options->check_host_ip = 1; 111618de8d7fSPeter Avalos if (options->strict_host_key_checking == -1) 111718de8d7fSPeter Avalos options->strict_host_key_checking = 2; /* 2 is default */ 111818de8d7fSPeter Avalos if (options->compression == -1) 111918de8d7fSPeter Avalos options->compression = 0; 112018de8d7fSPeter Avalos if (options->tcp_keep_alive == -1) 112118de8d7fSPeter Avalos options->tcp_keep_alive = 1; 112218de8d7fSPeter Avalos if (options->compression_level == -1) 112318de8d7fSPeter Avalos options->compression_level = 6; 112418de8d7fSPeter Avalos if (options->port == -1) 112518de8d7fSPeter Avalos options->port = 0; /* Filled in ssh_connect. */ 112618de8d7fSPeter Avalos if (options->address_family == -1) 112718de8d7fSPeter Avalos options->address_family = AF_UNSPEC; 112818de8d7fSPeter Avalos if (options->connection_attempts == -1) 112918de8d7fSPeter Avalos options->connection_attempts = 1; 113018de8d7fSPeter Avalos if (options->number_of_password_prompts == -1) 113118de8d7fSPeter Avalos options->number_of_password_prompts = 3; 113218de8d7fSPeter Avalos /* Selected in ssh_login(). */ 113318de8d7fSPeter Avalos if (options->cipher == -1) 113418de8d7fSPeter Avalos options->cipher = SSH_CIPHER_NOT_SET; 113518de8d7fSPeter Avalos /* options->ciphers, default set in myproposals.h */ 113618de8d7fSPeter Avalos /* options->macs, default set in myproposals.h */ 113718de8d7fSPeter Avalos /* options->hostkeyalgorithms, default set in myproposals.h */ 113818de8d7fSPeter Avalos if (options->protocol == SSH_PROTO_UNKNOWN) 113918de8d7fSPeter Avalos options->protocol = SSH_PROTO_1|SSH_PROTO_2; 114018de8d7fSPeter Avalos if (options->num_identity_files == 0) { 114118de8d7fSPeter Avalos if (options->protocol & SSH_PROTO_1) { 114218de8d7fSPeter Avalos len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 114318de8d7fSPeter Avalos options->identity_files[options->num_identity_files] = 114418de8d7fSPeter Avalos xmalloc(len); 114518de8d7fSPeter Avalos snprintf(options->identity_files[options->num_identity_files++], 114618de8d7fSPeter Avalos len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 114718de8d7fSPeter Avalos } 114818de8d7fSPeter Avalos if (options->protocol & SSH_PROTO_2) { 114918de8d7fSPeter Avalos len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 115018de8d7fSPeter Avalos options->identity_files[options->num_identity_files] = 115118de8d7fSPeter Avalos xmalloc(len); 115218de8d7fSPeter Avalos snprintf(options->identity_files[options->num_identity_files++], 115318de8d7fSPeter Avalos len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 115418de8d7fSPeter Avalos 115518de8d7fSPeter Avalos len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 115618de8d7fSPeter Avalos options->identity_files[options->num_identity_files] = 115718de8d7fSPeter Avalos xmalloc(len); 115818de8d7fSPeter Avalos snprintf(options->identity_files[options->num_identity_files++], 115918de8d7fSPeter Avalos len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 116018de8d7fSPeter Avalos } 116118de8d7fSPeter Avalos } 116218de8d7fSPeter Avalos if (options->escape_char == -1) 116318de8d7fSPeter Avalos options->escape_char = '~'; 116418de8d7fSPeter Avalos if (options->system_hostfile == NULL) 116518de8d7fSPeter Avalos options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; 116618de8d7fSPeter Avalos if (options->user_hostfile == NULL) 116718de8d7fSPeter Avalos options->user_hostfile = _PATH_SSH_USER_HOSTFILE; 116818de8d7fSPeter Avalos if (options->system_hostfile2 == NULL) 116918de8d7fSPeter Avalos options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; 117018de8d7fSPeter Avalos if (options->user_hostfile2 == NULL) 117118de8d7fSPeter Avalos options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; 117218de8d7fSPeter Avalos if (options->log_level == SYSLOG_LEVEL_NOT_SET) 117318de8d7fSPeter Avalos options->log_level = SYSLOG_LEVEL_INFO; 117418de8d7fSPeter Avalos if (options->clear_forwardings == 1) 117518de8d7fSPeter Avalos clear_forwardings(options); 117618de8d7fSPeter Avalos if (options->no_host_authentication_for_localhost == - 1) 117718de8d7fSPeter Avalos options->no_host_authentication_for_localhost = 0; 117818de8d7fSPeter Avalos if (options->identities_only == -1) 117918de8d7fSPeter Avalos options->identities_only = 0; 118018de8d7fSPeter Avalos if (options->enable_ssh_keysign == -1) 118118de8d7fSPeter Avalos options->enable_ssh_keysign = 0; 118218de8d7fSPeter Avalos if (options->rekey_limit == -1) 118318de8d7fSPeter Avalos options->rekey_limit = 0; 118418de8d7fSPeter Avalos if (options->verify_host_key_dns == -1) 118518de8d7fSPeter Avalos options->verify_host_key_dns = 0; 118618de8d7fSPeter Avalos if (options->server_alive_interval == -1) 118718de8d7fSPeter Avalos options->server_alive_interval = 0; 118818de8d7fSPeter Avalos if (options->server_alive_count_max == -1) 118918de8d7fSPeter Avalos options->server_alive_count_max = 3; 119018de8d7fSPeter Avalos if (options->control_master == -1) 119118de8d7fSPeter Avalos options->control_master = 0; 119218de8d7fSPeter Avalos if (options->hash_known_hosts == -1) 119318de8d7fSPeter Avalos options->hash_known_hosts = 0; 119418de8d7fSPeter Avalos if (options->tun_open == -1) 119518de8d7fSPeter Avalos options->tun_open = SSH_TUNMODE_NO; 119618de8d7fSPeter Avalos if (options->tun_local == -1) 119718de8d7fSPeter Avalos options->tun_local = SSH_TUNID_ANY; 119818de8d7fSPeter Avalos if (options->tun_remote == -1) 119918de8d7fSPeter Avalos options->tun_remote = SSH_TUNID_ANY; 120018de8d7fSPeter Avalos if (options->permit_local_command == -1) 120118de8d7fSPeter Avalos options->permit_local_command = 0; 120218de8d7fSPeter Avalos if (options->visual_host_key == -1) 120318de8d7fSPeter Avalos options->visual_host_key = 0; 1204*cb5eb4f1SPeter Avalos if (options->zero_knowledge_password_authentication == -1) 1205*cb5eb4f1SPeter Avalos options->zero_knowledge_password_authentication = 0; 120618de8d7fSPeter Avalos /* options->local_command should not be set by default */ 120718de8d7fSPeter Avalos /* options->proxy_command should not be set by default */ 120818de8d7fSPeter Avalos /* options->user will be set in the main program if appropriate */ 120918de8d7fSPeter Avalos /* options->hostname will be set in the main program if appropriate */ 121018de8d7fSPeter Avalos /* options->host_key_alias should not be set by default */ 121118de8d7fSPeter Avalos /* options->preferred_authentications will be set in ssh */ 121218de8d7fSPeter Avalos } 121318de8d7fSPeter Avalos 121418de8d7fSPeter Avalos /* 121518de8d7fSPeter Avalos * parse_forward 121618de8d7fSPeter Avalos * parses a string containing a port forwarding specification of the form: 1217*cb5eb4f1SPeter Avalos * dynamicfwd == 0 121818de8d7fSPeter Avalos * [listenhost:]listenport:connecthost:connectport 1219*cb5eb4f1SPeter Avalos * dynamicfwd == 1 1220*cb5eb4f1SPeter Avalos * [listenhost:]listenport 122118de8d7fSPeter Avalos * returns number of arguments parsed or zero on error 122218de8d7fSPeter Avalos */ 122318de8d7fSPeter Avalos int 1224*cb5eb4f1SPeter Avalos parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 122518de8d7fSPeter Avalos { 122618de8d7fSPeter Avalos int i; 122718de8d7fSPeter Avalos char *p, *cp, *fwdarg[4]; 122818de8d7fSPeter Avalos 122918de8d7fSPeter Avalos memset(fwd, '\0', sizeof(*fwd)); 123018de8d7fSPeter Avalos 123118de8d7fSPeter Avalos cp = p = xstrdup(fwdspec); 123218de8d7fSPeter Avalos 123318de8d7fSPeter Avalos /* skip leading spaces */ 123418de8d7fSPeter Avalos while (isspace(*cp)) 123518de8d7fSPeter Avalos cp++; 123618de8d7fSPeter Avalos 123718de8d7fSPeter Avalos for (i = 0; i < 4; ++i) 123818de8d7fSPeter Avalos if ((fwdarg[i] = hpdelim(&cp)) == NULL) 123918de8d7fSPeter Avalos break; 124018de8d7fSPeter Avalos 1241*cb5eb4f1SPeter Avalos /* Check for trailing garbage */ 124218de8d7fSPeter Avalos if (cp != NULL) 124318de8d7fSPeter Avalos i = 0; /* failure */ 124418de8d7fSPeter Avalos 124518de8d7fSPeter Avalos switch (i) { 1246*cb5eb4f1SPeter Avalos case 1: 1247*cb5eb4f1SPeter Avalos fwd->listen_host = NULL; 1248*cb5eb4f1SPeter Avalos fwd->listen_port = a2port(fwdarg[0]); 1249*cb5eb4f1SPeter Avalos fwd->connect_host = xstrdup("socks"); 1250*cb5eb4f1SPeter Avalos break; 1251*cb5eb4f1SPeter Avalos 1252*cb5eb4f1SPeter Avalos case 2: 1253*cb5eb4f1SPeter Avalos fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1254*cb5eb4f1SPeter Avalos fwd->listen_port = a2port(fwdarg[1]); 1255*cb5eb4f1SPeter Avalos fwd->connect_host = xstrdup("socks"); 1256*cb5eb4f1SPeter Avalos break; 1257*cb5eb4f1SPeter Avalos 125818de8d7fSPeter Avalos case 3: 125918de8d7fSPeter Avalos fwd->listen_host = NULL; 126018de8d7fSPeter Avalos fwd->listen_port = a2port(fwdarg[0]); 126118de8d7fSPeter Avalos fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); 126218de8d7fSPeter Avalos fwd->connect_port = a2port(fwdarg[2]); 126318de8d7fSPeter Avalos break; 126418de8d7fSPeter Avalos 126518de8d7fSPeter Avalos case 4: 126618de8d7fSPeter Avalos fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 126718de8d7fSPeter Avalos fwd->listen_port = a2port(fwdarg[1]); 126818de8d7fSPeter Avalos fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); 126918de8d7fSPeter Avalos fwd->connect_port = a2port(fwdarg[3]); 127018de8d7fSPeter Avalos break; 127118de8d7fSPeter Avalos default: 127218de8d7fSPeter Avalos i = 0; /* failure */ 127318de8d7fSPeter Avalos } 127418de8d7fSPeter Avalos 127518de8d7fSPeter Avalos xfree(p); 127618de8d7fSPeter Avalos 1277*cb5eb4f1SPeter Avalos if (dynamicfwd) { 1278*cb5eb4f1SPeter Avalos if (!(i == 1 || i == 2)) 1279*cb5eb4f1SPeter Avalos goto fail_free; 1280*cb5eb4f1SPeter Avalos } else { 1281*cb5eb4f1SPeter Avalos if (!(i == 3 || i == 4)) 1282*cb5eb4f1SPeter Avalos goto fail_free; 1283*cb5eb4f1SPeter Avalos if (fwd->connect_port <= 0) 1284*cb5eb4f1SPeter Avalos goto fail_free; 1285*cb5eb4f1SPeter Avalos } 1286*cb5eb4f1SPeter Avalos 1287*cb5eb4f1SPeter Avalos if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0)) 128818de8d7fSPeter Avalos goto fail_free; 128918de8d7fSPeter Avalos 129018de8d7fSPeter Avalos if (fwd->connect_host != NULL && 129118de8d7fSPeter Avalos strlen(fwd->connect_host) >= NI_MAXHOST) 129218de8d7fSPeter Avalos goto fail_free; 1293*cb5eb4f1SPeter Avalos if (fwd->listen_host != NULL && 1294*cb5eb4f1SPeter Avalos strlen(fwd->listen_host) >= NI_MAXHOST) 1295*cb5eb4f1SPeter Avalos goto fail_free; 1296*cb5eb4f1SPeter Avalos 129718de8d7fSPeter Avalos 129818de8d7fSPeter Avalos return (i); 129918de8d7fSPeter Avalos 130018de8d7fSPeter Avalos fail_free: 1301*cb5eb4f1SPeter Avalos if (fwd->connect_host != NULL) { 130218de8d7fSPeter Avalos xfree(fwd->connect_host); 1303*cb5eb4f1SPeter Avalos fwd->connect_host = NULL; 1304*cb5eb4f1SPeter Avalos } 1305*cb5eb4f1SPeter Avalos if (fwd->listen_host != NULL) { 130618de8d7fSPeter Avalos xfree(fwd->listen_host); 1307*cb5eb4f1SPeter Avalos fwd->listen_host = NULL; 1308*cb5eb4f1SPeter Avalos } 130918de8d7fSPeter Avalos return (0); 131018de8d7fSPeter Avalos } 1311