10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * Author: Tatu Ylonen <ylo@cs.hut.fi> 30Sstevel@tonic-gate * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 40Sstevel@tonic-gate * All rights reserved 50Sstevel@tonic-gate * Functions for reading the configuration files. 60Sstevel@tonic-gate * 70Sstevel@tonic-gate * As far as I am concerned, the code I have written for this software 80Sstevel@tonic-gate * can be used freely for any purpose. Any derived versions of this 90Sstevel@tonic-gate * software must be clearly marked as such, and if the derived work is 100Sstevel@tonic-gate * incompatible with the protocol description in the RFC file, it must be 110Sstevel@tonic-gate * called by a name other than "ssh" or "Secure Shell". 120Sstevel@tonic-gate */ 130Sstevel@tonic-gate /* 143946Sjp161948 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 150Sstevel@tonic-gate * Use is subject to license terms. 160Sstevel@tonic-gate */ 170Sstevel@tonic-gate 180Sstevel@tonic-gate #include "includes.h" 190Sstevel@tonic-gate RCSID("$OpenBSD: readconf.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $"); 200Sstevel@tonic-gate 210Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 220Sstevel@tonic-gate 230Sstevel@tonic-gate #include "ssh.h" 240Sstevel@tonic-gate #include "xmalloc.h" 250Sstevel@tonic-gate #include "compat.h" 260Sstevel@tonic-gate #include "cipher.h" 270Sstevel@tonic-gate #include "pathnames.h" 280Sstevel@tonic-gate #include "log.h" 290Sstevel@tonic-gate #include "readconf.h" 300Sstevel@tonic-gate #include "match.h" 310Sstevel@tonic-gate #include "misc.h" 320Sstevel@tonic-gate #include "kex.h" 330Sstevel@tonic-gate #include "mac.h" 340Sstevel@tonic-gate 350Sstevel@tonic-gate /* Format of the configuration file: 360Sstevel@tonic-gate 370Sstevel@tonic-gate # Configuration data is parsed as follows: 380Sstevel@tonic-gate # 1. command line options 390Sstevel@tonic-gate # 2. user-specific file 400Sstevel@tonic-gate # 3. system-wide file 410Sstevel@tonic-gate # Any configuration value is only changed the first time it is set. 420Sstevel@tonic-gate # Thus, host-specific definitions should be at the beginning of the 430Sstevel@tonic-gate # configuration file, and defaults at the end. 440Sstevel@tonic-gate 450Sstevel@tonic-gate # Host-specific declarations. These may override anything above. A single 460Sstevel@tonic-gate # host may match multiple declarations; these are processed in the order 470Sstevel@tonic-gate # that they are given in. 480Sstevel@tonic-gate 490Sstevel@tonic-gate Host *.ngs.fi ngs.fi 500Sstevel@tonic-gate User foo 510Sstevel@tonic-gate 520Sstevel@tonic-gate Host fake.com 530Sstevel@tonic-gate HostName another.host.name.real.org 540Sstevel@tonic-gate User blaah 550Sstevel@tonic-gate Port 34289 560Sstevel@tonic-gate ForwardX11 no 570Sstevel@tonic-gate ForwardAgent no 580Sstevel@tonic-gate 590Sstevel@tonic-gate Host books.com 600Sstevel@tonic-gate RemoteForward 9999 shadows.cs.hut.fi:9999 610Sstevel@tonic-gate Cipher 3des 620Sstevel@tonic-gate 630Sstevel@tonic-gate Host fascist.blob.com 640Sstevel@tonic-gate Port 23123 650Sstevel@tonic-gate User tylonen 660Sstevel@tonic-gate RhostsAuthentication no 670Sstevel@tonic-gate PasswordAuthentication no 680Sstevel@tonic-gate 690Sstevel@tonic-gate Host puukko.hut.fi 700Sstevel@tonic-gate User t35124p 710Sstevel@tonic-gate ProxyCommand ssh-proxy %h %p 720Sstevel@tonic-gate 730Sstevel@tonic-gate Host *.fr 740Sstevel@tonic-gate PublicKeyAuthentication no 750Sstevel@tonic-gate 760Sstevel@tonic-gate Host *.su 770Sstevel@tonic-gate Cipher none 780Sstevel@tonic-gate PasswordAuthentication no 790Sstevel@tonic-gate 800Sstevel@tonic-gate # Defaults for various options 810Sstevel@tonic-gate Host * 820Sstevel@tonic-gate ForwardAgent no 830Sstevel@tonic-gate ForwardX11 no 840Sstevel@tonic-gate RhostsAuthentication yes 850Sstevel@tonic-gate PasswordAuthentication yes 860Sstevel@tonic-gate RSAAuthentication yes 870Sstevel@tonic-gate RhostsRSAAuthentication yes 880Sstevel@tonic-gate StrictHostKeyChecking yes 890Sstevel@tonic-gate KeepAlives no 900Sstevel@tonic-gate IdentityFile ~/.ssh/identity 910Sstevel@tonic-gate Port 22 920Sstevel@tonic-gate EscapeChar ~ 930Sstevel@tonic-gate 940Sstevel@tonic-gate */ 950Sstevel@tonic-gate 960Sstevel@tonic-gate /* Keyword tokens. */ 970Sstevel@tonic-gate 980Sstevel@tonic-gate typedef enum { 990Sstevel@tonic-gate oBadOption, 1000Sstevel@tonic-gate oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, 1010Sstevel@tonic-gate oPasswordAuthentication, oRSAAuthentication, 1020Sstevel@tonic-gate oChallengeResponseAuthentication, oXAuthLocation, 1030Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 1040Sstevel@tonic-gate oKerberosAuthentication, 1050Sstevel@tonic-gate #endif 1060Sstevel@tonic-gate #ifdef GSSAPI 1070Sstevel@tonic-gate oGssKeyEx, oGssAuthentication, oGssDelegateCreds, 1080Sstevel@tonic-gate #ifdef GSI 1090Sstevel@tonic-gate oGssGlobusDelegateLimitedCreds, 1100Sstevel@tonic-gate #endif /* GSI */ 1110Sstevel@tonic-gate #endif /* GSSAPI */ 1120Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 1130Sstevel@tonic-gate oKerberosTgtPassing, 1140Sstevel@tonic-gate #endif 1150Sstevel@tonic-gate #ifdef AFS 1160Sstevel@tonic-gate oAFSTokenPassing, 1170Sstevel@tonic-gate #endif 1180Sstevel@tonic-gate oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 1190Sstevel@tonic-gate oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 1200Sstevel@tonic-gate oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 1210Sstevel@tonic-gate oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 1220Sstevel@tonic-gate oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, 1230Sstevel@tonic-gate oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 1240Sstevel@tonic-gate oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 1250Sstevel@tonic-gate oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 1260Sstevel@tonic-gate oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 1270Sstevel@tonic-gate oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, 1280Sstevel@tonic-gate oClearAllForwardings, oNoHostAuthenticationForLocalhost, 1293946Sjp161948 oFallBackToRsh, oUseRsh, oConnectTimeout, 1300Sstevel@tonic-gate oDeprecated 1310Sstevel@tonic-gate } OpCodes; 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate /* Textual representations of the tokens. */ 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate static struct { 1360Sstevel@tonic-gate const char *name; 1370Sstevel@tonic-gate OpCodes opcode; 1380Sstevel@tonic-gate } keywords[] = { 1390Sstevel@tonic-gate { "forwardagent", oForwardAgent }, 1400Sstevel@tonic-gate { "forwardx11", oForwardX11 }, 1410Sstevel@tonic-gate { "xauthlocation", oXAuthLocation }, 1420Sstevel@tonic-gate { "gatewayports", oGatewayPorts }, 1430Sstevel@tonic-gate { "useprivilegedport", oUsePrivilegedPort }, 1440Sstevel@tonic-gate { "rhostsauthentication", oRhostsAuthentication }, 1450Sstevel@tonic-gate { "passwordauthentication", oPasswordAuthentication }, 1460Sstevel@tonic-gate { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 1470Sstevel@tonic-gate { "kbdinteractivedevices", oKbdInteractiveDevices }, 1480Sstevel@tonic-gate { "rsaauthentication", oRSAAuthentication }, 1490Sstevel@tonic-gate { "pubkeyauthentication", oPubkeyAuthentication }, 1500Sstevel@tonic-gate { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 1510Sstevel@tonic-gate { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 1520Sstevel@tonic-gate { "hostbasedauthentication", oHostbasedAuthentication }, 1530Sstevel@tonic-gate { "challengeresponseauthentication", oChallengeResponseAuthentication }, 1540Sstevel@tonic-gate { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 1550Sstevel@tonic-gate { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 1560Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 1570Sstevel@tonic-gate { "kerberosauthentication", oKerberosAuthentication }, 1580Sstevel@tonic-gate #endif 1590Sstevel@tonic-gate #ifdef GSSAPI 1600Sstevel@tonic-gate { "gssapikeyexchange", oGssKeyEx }, 1610Sstevel@tonic-gate { "gssapiauthentication", oGssAuthentication }, 1620Sstevel@tonic-gate { "gssapidelegatecredentials", oGssDelegateCreds }, 1630Sstevel@tonic-gate { "gsskeyex", oGssKeyEx }, /* alias */ 1640Sstevel@tonic-gate { "gssauthentication", oGssAuthentication }, /* alias */ 1650Sstevel@tonic-gate { "gssdelegatecreds", oGssDelegateCreds }, /* alias */ 1660Sstevel@tonic-gate #ifdef GSI 1670Sstevel@tonic-gate /* For backwards compatability with old 1.2.27 client code */ 1680Sstevel@tonic-gate { "forwardgssapiglobusproxy", oGssDelegateCreds }, /* alias */ 1690Sstevel@tonic-gate { "forwardgssapiglobuslimitedproxy", oGssGlobusDelegateLimitedCreds }, 1700Sstevel@tonic-gate #endif /* GSI */ 1710Sstevel@tonic-gate #endif /* GSSAPI */ 1720Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 1730Sstevel@tonic-gate { "kerberostgtpassing", oKerberosTgtPassing }, 1740Sstevel@tonic-gate #endif 1750Sstevel@tonic-gate #ifdef AFS 1760Sstevel@tonic-gate { "afstokenpassing", oAFSTokenPassing }, 1770Sstevel@tonic-gate #endif 1780Sstevel@tonic-gate { "fallbacktorsh", oFallBackToRsh }, 1790Sstevel@tonic-gate { "usersh", oUseRsh }, 1800Sstevel@tonic-gate { "identityfile", oIdentityFile }, 1810Sstevel@tonic-gate { "identityfile2", oIdentityFile }, /* alias */ 1820Sstevel@tonic-gate { "hostname", oHostName }, 1830Sstevel@tonic-gate { "hostkeyalias", oHostKeyAlias }, 1840Sstevel@tonic-gate { "proxycommand", oProxyCommand }, 1850Sstevel@tonic-gate { "port", oPort }, 1860Sstevel@tonic-gate { "cipher", oCipher }, 1870Sstevel@tonic-gate { "ciphers", oCiphers }, 1880Sstevel@tonic-gate { "macs", oMacs }, 1890Sstevel@tonic-gate { "protocol", oProtocol }, 1900Sstevel@tonic-gate { "remoteforward", oRemoteForward }, 1910Sstevel@tonic-gate { "localforward", oLocalForward }, 1920Sstevel@tonic-gate { "user", oUser }, 1930Sstevel@tonic-gate { "host", oHost }, 1940Sstevel@tonic-gate { "escapechar", oEscapeChar }, 1950Sstevel@tonic-gate { "globalknownhostsfile", oGlobalKnownHostsFile }, 1960Sstevel@tonic-gate { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */ 1970Sstevel@tonic-gate { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, 1980Sstevel@tonic-gate { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ 1990Sstevel@tonic-gate { "connectionattempts", oConnectionAttempts }, 2000Sstevel@tonic-gate { "batchmode", oBatchMode }, 2010Sstevel@tonic-gate { "checkhostip", oCheckHostIP }, 2020Sstevel@tonic-gate { "stricthostkeychecking", oStrictHostKeyChecking }, 2030Sstevel@tonic-gate { "compression", oCompression }, 2040Sstevel@tonic-gate { "compressionlevel", oCompressionLevel }, 2050Sstevel@tonic-gate { "keepalive", oKeepAlives }, 2060Sstevel@tonic-gate { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 2070Sstevel@tonic-gate { "loglevel", oLogLevel }, 2080Sstevel@tonic-gate { "dynamicforward", oDynamicForward }, 2090Sstevel@tonic-gate { "preferredauthentications", oPreferredAuthentications }, 2100Sstevel@tonic-gate { "hostkeyalgorithms", oHostKeyAlgorithms }, 2110Sstevel@tonic-gate { "bindaddress", oBindAddress }, 2120Sstevel@tonic-gate { "smartcarddevice", oSmartcardDevice }, 2130Sstevel@tonic-gate { "clearallforwardings", oClearAllForwardings }, 2140Sstevel@tonic-gate { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 2153946Sjp161948 { "connecttimeout", oConnectTimeout }, 2160Sstevel@tonic-gate { NULL, oBadOption } 2170Sstevel@tonic-gate }; 2180Sstevel@tonic-gate 2190Sstevel@tonic-gate /* 2200Sstevel@tonic-gate * Adds a local TCP/IP port forward to options. Never returns if there is an 2210Sstevel@tonic-gate * error. 2220Sstevel@tonic-gate */ 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate void 2250Sstevel@tonic-gate add_local_forward(Options *options, u_short port, const char *host, 2260Sstevel@tonic-gate u_short host_port) 2270Sstevel@tonic-gate { 2280Sstevel@tonic-gate Forward *fwd; 2290Sstevel@tonic-gate #ifndef NO_IPPORT_RESERVED_CONCEPT 2300Sstevel@tonic-gate extern uid_t original_real_uid; 2310Sstevel@tonic-gate if (port < IPPORT_RESERVED && original_real_uid != 0) 2320Sstevel@tonic-gate fatal("Privileged ports can only be forwarded by root."); 2330Sstevel@tonic-gate #endif 2340Sstevel@tonic-gate if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 2350Sstevel@tonic-gate fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 2360Sstevel@tonic-gate fwd = &options->local_forwards[options->num_local_forwards++]; 2370Sstevel@tonic-gate fwd->port = port; 2380Sstevel@tonic-gate fwd->host = xstrdup(host); 2390Sstevel@tonic-gate fwd->host_port = host_port; 2400Sstevel@tonic-gate } 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate /* 2430Sstevel@tonic-gate * Adds a remote TCP/IP port forward to options. Never returns if there is 2440Sstevel@tonic-gate * an error. 2450Sstevel@tonic-gate */ 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate void 2480Sstevel@tonic-gate add_remote_forward(Options *options, u_short port, const char *host, 2490Sstevel@tonic-gate u_short host_port) 2500Sstevel@tonic-gate { 2510Sstevel@tonic-gate Forward *fwd; 2520Sstevel@tonic-gate if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 2530Sstevel@tonic-gate fatal("Too many remote forwards (max %d).", 2540Sstevel@tonic-gate SSH_MAX_FORWARDS_PER_DIRECTION); 2550Sstevel@tonic-gate fwd = &options->remote_forwards[options->num_remote_forwards++]; 2560Sstevel@tonic-gate fwd->port = port; 2570Sstevel@tonic-gate fwd->host = xstrdup(host); 2580Sstevel@tonic-gate fwd->host_port = host_port; 2590Sstevel@tonic-gate } 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate static void 2620Sstevel@tonic-gate clear_forwardings(Options *options) 2630Sstevel@tonic-gate { 2640Sstevel@tonic-gate int i; 2650Sstevel@tonic-gate 2660Sstevel@tonic-gate for (i = 0; i < options->num_local_forwards; i++) 2670Sstevel@tonic-gate xfree(options->local_forwards[i].host); 2680Sstevel@tonic-gate options->num_local_forwards = 0; 2690Sstevel@tonic-gate for (i = 0; i < options->num_remote_forwards; i++) 2700Sstevel@tonic-gate xfree(options->remote_forwards[i].host); 2710Sstevel@tonic-gate options->num_remote_forwards = 0; 2720Sstevel@tonic-gate } 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate /* 2750Sstevel@tonic-gate * Returns the number of the token pointed to by cp or oBadOption. 2760Sstevel@tonic-gate */ 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate static OpCodes 2790Sstevel@tonic-gate parse_token(const char *cp, const char *filename, int linenum) 2800Sstevel@tonic-gate { 2810Sstevel@tonic-gate u_int i; 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate for (i = 0; keywords[i].name; i++) 2840Sstevel@tonic-gate if (strcasecmp(cp, keywords[i].name) == 0) 2850Sstevel@tonic-gate return keywords[i].opcode; 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate error("%s: line %d: Bad configuration option: %s", 2880Sstevel@tonic-gate filename, linenum, cp); 2890Sstevel@tonic-gate return oBadOption; 2900Sstevel@tonic-gate } 2910Sstevel@tonic-gate 2920Sstevel@tonic-gate /* 2930Sstevel@tonic-gate * Processes a single option line as used in the configuration files. This 2940Sstevel@tonic-gate * only sets those values that have not already been set. 2950Sstevel@tonic-gate */ 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate int 2980Sstevel@tonic-gate process_config_line(Options *options, const char *host, 2990Sstevel@tonic-gate char *line, const char *filename, int linenum, 3000Sstevel@tonic-gate int *activep) 3010Sstevel@tonic-gate { 3020Sstevel@tonic-gate char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg; 3030Sstevel@tonic-gate int opcode, *intptr, value; 3040Sstevel@tonic-gate u_short fwd_port, fwd_host_port; 3050Sstevel@tonic-gate char sfwd_host_port[6]; 3060Sstevel@tonic-gate 3070Sstevel@tonic-gate s = line; 3080Sstevel@tonic-gate /* Get the keyword. (Each line is supposed to begin with a keyword). */ 3090Sstevel@tonic-gate keyword = strdelim(&s); 3100Sstevel@tonic-gate /* Ignore leading whitespace. */ 3110Sstevel@tonic-gate if (*keyword == '\0') 3120Sstevel@tonic-gate keyword = strdelim(&s); 3130Sstevel@tonic-gate if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 3140Sstevel@tonic-gate return 0; 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate opcode = parse_token(keyword, filename, linenum); 3170Sstevel@tonic-gate 3180Sstevel@tonic-gate switch (opcode) { 3190Sstevel@tonic-gate case oBadOption: 3200Sstevel@tonic-gate /* don't panic, but count bad options */ 3210Sstevel@tonic-gate return -1; 3220Sstevel@tonic-gate /* NOTREACHED */ 3233946Sjp161948 case oConnectTimeout: 3243946Sjp161948 intptr = &options->connection_timeout; 3253946Sjp161948 parse_time: 3263946Sjp161948 arg = strdelim(&s); 3273946Sjp161948 if (!arg || *arg == '\0') 3283946Sjp161948 fatal("%s line %d: missing time value.", 3293946Sjp161948 filename, linenum); 3303946Sjp161948 if ((value = convtime(arg)) == -1) 3313946Sjp161948 fatal("%s line %d: invalid time value.", 3323946Sjp161948 filename, linenum); 333*3984Sjp161948 if (*activep && *intptr == -1) 3343946Sjp161948 *intptr = value; 3353946Sjp161948 break; 3363946Sjp161948 3370Sstevel@tonic-gate case oForwardAgent: 3380Sstevel@tonic-gate intptr = &options->forward_agent; 3390Sstevel@tonic-gate parse_flag: 3400Sstevel@tonic-gate arg = strdelim(&s); 3410Sstevel@tonic-gate if (!arg || *arg == '\0') 3420Sstevel@tonic-gate fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 3430Sstevel@tonic-gate value = 0; /* To avoid compiler warning... */ 3440Sstevel@tonic-gate if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 3450Sstevel@tonic-gate value = 1; 3460Sstevel@tonic-gate else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 3470Sstevel@tonic-gate value = 0; 3480Sstevel@tonic-gate else 3490Sstevel@tonic-gate fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 3500Sstevel@tonic-gate if (*activep && *intptr == -1) 3510Sstevel@tonic-gate *intptr = value; 3520Sstevel@tonic-gate break; 3530Sstevel@tonic-gate 3540Sstevel@tonic-gate case oForwardX11: 3550Sstevel@tonic-gate intptr = &options->forward_x11; 3560Sstevel@tonic-gate goto parse_flag; 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate case oGatewayPorts: 3590Sstevel@tonic-gate intptr = &options->gateway_ports; 3600Sstevel@tonic-gate goto parse_flag; 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate case oUsePrivilegedPort: 3630Sstevel@tonic-gate intptr = &options->use_privileged_port; 3640Sstevel@tonic-gate goto parse_flag; 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate case oRhostsAuthentication: 3670Sstevel@tonic-gate intptr = &options->rhosts_authentication; 3680Sstevel@tonic-gate goto parse_flag; 3690Sstevel@tonic-gate 3700Sstevel@tonic-gate case oPasswordAuthentication: 3710Sstevel@tonic-gate intptr = &options->password_authentication; 3720Sstevel@tonic-gate goto parse_flag; 3730Sstevel@tonic-gate 3740Sstevel@tonic-gate case oKbdInteractiveAuthentication: 3750Sstevel@tonic-gate intptr = &options->kbd_interactive_authentication; 3760Sstevel@tonic-gate goto parse_flag; 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate case oKbdInteractiveDevices: 3790Sstevel@tonic-gate charptr = &options->kbd_interactive_devices; 3800Sstevel@tonic-gate goto parse_string; 3810Sstevel@tonic-gate 3820Sstevel@tonic-gate case oPubkeyAuthentication: 3830Sstevel@tonic-gate intptr = &options->pubkey_authentication; 3840Sstevel@tonic-gate goto parse_flag; 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate case oRSAAuthentication: 3870Sstevel@tonic-gate intptr = &options->rsa_authentication; 3880Sstevel@tonic-gate goto parse_flag; 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate case oRhostsRSAAuthentication: 3910Sstevel@tonic-gate intptr = &options->rhosts_rsa_authentication; 3920Sstevel@tonic-gate goto parse_flag; 3930Sstevel@tonic-gate 3940Sstevel@tonic-gate case oHostbasedAuthentication: 3950Sstevel@tonic-gate intptr = &options->hostbased_authentication; 3960Sstevel@tonic-gate goto parse_flag; 3970Sstevel@tonic-gate 3980Sstevel@tonic-gate case oChallengeResponseAuthentication: 3990Sstevel@tonic-gate intptr = &options->challenge_response_authentication; 4000Sstevel@tonic-gate goto parse_flag; 4010Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 4020Sstevel@tonic-gate case oKerberosAuthentication: 4030Sstevel@tonic-gate intptr = &options->kerberos_authentication; 4040Sstevel@tonic-gate goto parse_flag; 4050Sstevel@tonic-gate #endif 4060Sstevel@tonic-gate #ifdef GSSAPI 4070Sstevel@tonic-gate case oGssKeyEx: 4080Sstevel@tonic-gate intptr = &options->gss_keyex; 4090Sstevel@tonic-gate goto parse_flag; 4100Sstevel@tonic-gate 4110Sstevel@tonic-gate case oGssAuthentication: 4120Sstevel@tonic-gate intptr = &options->gss_authentication; 4130Sstevel@tonic-gate goto parse_flag; 4140Sstevel@tonic-gate 4150Sstevel@tonic-gate case oGssDelegateCreds: 4160Sstevel@tonic-gate intptr = &options->gss_deleg_creds; 4170Sstevel@tonic-gate goto parse_flag; 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate #ifdef GSI 4200Sstevel@tonic-gate case oGssGlobusDelegateLimitedCreds: 4210Sstevel@tonic-gate intptr = &options->gss_globus_deleg_limited_proxy; 4220Sstevel@tonic-gate goto parse_flag; 4230Sstevel@tonic-gate #endif /* GSI */ 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate #endif /* GSSAPI */ 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 4280Sstevel@tonic-gate case oKerberosTgtPassing: 4290Sstevel@tonic-gate intptr = &options->kerberos_tgt_passing; 4300Sstevel@tonic-gate goto parse_flag; 4310Sstevel@tonic-gate #endif 4320Sstevel@tonic-gate #ifdef AFS 4330Sstevel@tonic-gate case oAFSTokenPassing: 4340Sstevel@tonic-gate intptr = &options->afs_token_passing; 4350Sstevel@tonic-gate goto parse_flag; 4360Sstevel@tonic-gate #endif 4370Sstevel@tonic-gate case oFallBackToRsh: 4380Sstevel@tonic-gate intptr = &options->fallback_to_rsh; 4390Sstevel@tonic-gate goto parse_flag; 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate case oUseRsh: 4420Sstevel@tonic-gate intptr = &options->use_rsh; 4430Sstevel@tonic-gate goto parse_flag; 4440Sstevel@tonic-gate 4450Sstevel@tonic-gate case oBatchMode: 4460Sstevel@tonic-gate intptr = &options->batch_mode; 4470Sstevel@tonic-gate goto parse_flag; 4480Sstevel@tonic-gate 4490Sstevel@tonic-gate case oCheckHostIP: 4500Sstevel@tonic-gate intptr = &options->check_host_ip; 4510Sstevel@tonic-gate goto parse_flag; 4520Sstevel@tonic-gate 4530Sstevel@tonic-gate case oStrictHostKeyChecking: 4540Sstevel@tonic-gate intptr = &options->strict_host_key_checking; 4550Sstevel@tonic-gate arg = strdelim(&s); 4560Sstevel@tonic-gate if (!arg || *arg == '\0') 4570Sstevel@tonic-gate fatal("%.200s line %d: Missing yes/no/ask argument.", 4580Sstevel@tonic-gate filename, linenum); 4590Sstevel@tonic-gate value = 0; /* To avoid compiler warning... */ 4600Sstevel@tonic-gate if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 4610Sstevel@tonic-gate value = 1; 4620Sstevel@tonic-gate else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 4630Sstevel@tonic-gate value = 0; 4640Sstevel@tonic-gate else if (strcmp(arg, "ask") == 0) 4650Sstevel@tonic-gate value = 2; 4660Sstevel@tonic-gate else 4670Sstevel@tonic-gate fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 4680Sstevel@tonic-gate if (*activep && *intptr == -1) 4690Sstevel@tonic-gate *intptr = value; 4700Sstevel@tonic-gate break; 4710Sstevel@tonic-gate 4720Sstevel@tonic-gate case oCompression: 4730Sstevel@tonic-gate intptr = &options->compression; 4740Sstevel@tonic-gate goto parse_flag; 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate case oKeepAlives: 4770Sstevel@tonic-gate intptr = &options->keepalives; 4780Sstevel@tonic-gate goto parse_flag; 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate case oNoHostAuthenticationForLocalhost: 4810Sstevel@tonic-gate intptr = &options->no_host_authentication_for_localhost; 4820Sstevel@tonic-gate goto parse_flag; 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate case oNumberOfPasswordPrompts: 4850Sstevel@tonic-gate intptr = &options->number_of_password_prompts; 4860Sstevel@tonic-gate goto parse_int; 4870Sstevel@tonic-gate 4880Sstevel@tonic-gate case oCompressionLevel: 4890Sstevel@tonic-gate intptr = &options->compression_level; 4900Sstevel@tonic-gate goto parse_int; 4910Sstevel@tonic-gate 4920Sstevel@tonic-gate case oIdentityFile: 4930Sstevel@tonic-gate arg = strdelim(&s); 4940Sstevel@tonic-gate if (!arg || *arg == '\0') 4950Sstevel@tonic-gate fatal("%.200s line %d: Missing argument.", filename, linenum); 4960Sstevel@tonic-gate if (*activep) { 4970Sstevel@tonic-gate intptr = &options->num_identity_files; 4980Sstevel@tonic-gate if (*intptr >= SSH_MAX_IDENTITY_FILES) 4990Sstevel@tonic-gate fatal("%.200s line %d: Too many identity files specified (max %d).", 5000Sstevel@tonic-gate filename, linenum, SSH_MAX_IDENTITY_FILES); 5010Sstevel@tonic-gate charptr = &options->identity_files[*intptr]; 5020Sstevel@tonic-gate *charptr = xstrdup(arg); 5030Sstevel@tonic-gate *intptr = *intptr + 1; 5040Sstevel@tonic-gate } 5050Sstevel@tonic-gate break; 5060Sstevel@tonic-gate 5070Sstevel@tonic-gate case oXAuthLocation: 5080Sstevel@tonic-gate charptr=&options->xauth_location; 5090Sstevel@tonic-gate goto parse_string; 5100Sstevel@tonic-gate 5110Sstevel@tonic-gate case oUser: 5120Sstevel@tonic-gate charptr = &options->user; 5130Sstevel@tonic-gate parse_string: 5140Sstevel@tonic-gate arg = strdelim(&s); 5150Sstevel@tonic-gate if (!arg || *arg == '\0') 5160Sstevel@tonic-gate fatal("%.200s line %d: Missing argument.", filename, linenum); 5170Sstevel@tonic-gate if (*activep && *charptr == NULL) 5180Sstevel@tonic-gate *charptr = xstrdup(arg); 5190Sstevel@tonic-gate break; 5200Sstevel@tonic-gate 5210Sstevel@tonic-gate case oGlobalKnownHostsFile: 5220Sstevel@tonic-gate charptr = &options->system_hostfile; 5230Sstevel@tonic-gate goto parse_string; 5240Sstevel@tonic-gate 5250Sstevel@tonic-gate case oUserKnownHostsFile: 5260Sstevel@tonic-gate charptr = &options->user_hostfile; 5270Sstevel@tonic-gate goto parse_string; 5280Sstevel@tonic-gate 5290Sstevel@tonic-gate case oGlobalKnownHostsFile2: 5300Sstevel@tonic-gate charptr = &options->system_hostfile2; 5310Sstevel@tonic-gate goto parse_string; 5320Sstevel@tonic-gate 5330Sstevel@tonic-gate case oUserKnownHostsFile2: 5340Sstevel@tonic-gate charptr = &options->user_hostfile2; 5350Sstevel@tonic-gate goto parse_string; 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate case oHostName: 5380Sstevel@tonic-gate charptr = &options->hostname; 5390Sstevel@tonic-gate goto parse_string; 5400Sstevel@tonic-gate 5410Sstevel@tonic-gate case oHostKeyAlias: 5420Sstevel@tonic-gate charptr = &options->host_key_alias; 5430Sstevel@tonic-gate goto parse_string; 5440Sstevel@tonic-gate 5450Sstevel@tonic-gate case oPreferredAuthentications: 5460Sstevel@tonic-gate charptr = &options->preferred_authentications; 5470Sstevel@tonic-gate goto parse_string; 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate case oBindAddress: 5500Sstevel@tonic-gate charptr = &options->bind_address; 5510Sstevel@tonic-gate goto parse_string; 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate case oSmartcardDevice: 5540Sstevel@tonic-gate charptr = &options->smartcard_device; 5550Sstevel@tonic-gate goto parse_string; 5560Sstevel@tonic-gate 5570Sstevel@tonic-gate case oProxyCommand: 5580Sstevel@tonic-gate charptr = &options->proxy_command; 5590Sstevel@tonic-gate string = xstrdup(""); 5600Sstevel@tonic-gate while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 5610Sstevel@tonic-gate string = xrealloc(string, strlen(string) + strlen(arg) + 2); 5620Sstevel@tonic-gate strcat(string, " "); 5630Sstevel@tonic-gate strcat(string, arg); 5640Sstevel@tonic-gate } 5650Sstevel@tonic-gate if (*activep && *charptr == NULL) 5660Sstevel@tonic-gate *charptr = string; 5670Sstevel@tonic-gate else 5680Sstevel@tonic-gate xfree(string); 5690Sstevel@tonic-gate return 0; 5700Sstevel@tonic-gate 5710Sstevel@tonic-gate case oPort: 5720Sstevel@tonic-gate intptr = &options->port; 5730Sstevel@tonic-gate parse_int: 5740Sstevel@tonic-gate arg = strdelim(&s); 5750Sstevel@tonic-gate if (!arg || *arg == '\0') 5760Sstevel@tonic-gate fatal("%.200s line %d: Missing argument.", filename, linenum); 5770Sstevel@tonic-gate if (arg[0] < '0' || arg[0] > '9') 5780Sstevel@tonic-gate fatal("%.200s line %d: Bad number.", filename, linenum); 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate /* Octal, decimal, or hex format? */ 5810Sstevel@tonic-gate value = strtol(arg, &endofnumber, 0); 5820Sstevel@tonic-gate if (arg == endofnumber) 5830Sstevel@tonic-gate fatal("%.200s line %d: Bad number.", filename, linenum); 5840Sstevel@tonic-gate if (*activep && *intptr == -1) 5850Sstevel@tonic-gate *intptr = value; 5860Sstevel@tonic-gate break; 5870Sstevel@tonic-gate 5880Sstevel@tonic-gate case oConnectionAttempts: 5890Sstevel@tonic-gate intptr = &options->connection_attempts; 5900Sstevel@tonic-gate goto parse_int; 5910Sstevel@tonic-gate 5920Sstevel@tonic-gate case oCipher: 5930Sstevel@tonic-gate intptr = &options->cipher; 5940Sstevel@tonic-gate arg = strdelim(&s); 5950Sstevel@tonic-gate if (!arg || *arg == '\0') 5960Sstevel@tonic-gate fatal("%.200s line %d: Missing argument.", filename, linenum); 5970Sstevel@tonic-gate value = cipher_number(arg); 5980Sstevel@tonic-gate if (value == -1) 5990Sstevel@tonic-gate fatal("%.200s line %d: Bad cipher '%s'.", 6000Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 6010Sstevel@tonic-gate if (*activep && *intptr == -1) 6020Sstevel@tonic-gate *intptr = value; 6030Sstevel@tonic-gate break; 6040Sstevel@tonic-gate 6050Sstevel@tonic-gate case oCiphers: 6060Sstevel@tonic-gate arg = strdelim(&s); 6070Sstevel@tonic-gate if (!arg || *arg == '\0') 6080Sstevel@tonic-gate fatal("%.200s line %d: Missing argument.", filename, linenum); 6090Sstevel@tonic-gate if (!ciphers_valid(arg)) 6100Sstevel@tonic-gate fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 6110Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 6120Sstevel@tonic-gate if (*activep && options->ciphers == NULL) 6130Sstevel@tonic-gate options->ciphers = xstrdup(arg); 6140Sstevel@tonic-gate break; 6150Sstevel@tonic-gate 6160Sstevel@tonic-gate case oMacs: 6170Sstevel@tonic-gate arg = strdelim(&s); 6180Sstevel@tonic-gate if (!arg || *arg == '\0') 6190Sstevel@tonic-gate fatal("%.200s line %d: Missing argument.", filename, linenum); 6200Sstevel@tonic-gate if (!mac_valid(arg)) 6210Sstevel@tonic-gate fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 6220Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 6230Sstevel@tonic-gate if (*activep && options->macs == NULL) 6240Sstevel@tonic-gate options->macs = xstrdup(arg); 6250Sstevel@tonic-gate break; 6260Sstevel@tonic-gate 6270Sstevel@tonic-gate case oHostKeyAlgorithms: 6280Sstevel@tonic-gate arg = strdelim(&s); 6290Sstevel@tonic-gate if (!arg || *arg == '\0') 6300Sstevel@tonic-gate fatal("%.200s line %d: Missing argument.", filename, linenum); 6310Sstevel@tonic-gate if (!key_names_valid2(arg)) 6320Sstevel@tonic-gate fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 6330Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 6340Sstevel@tonic-gate if (*activep && options->hostkeyalgorithms == NULL) 6350Sstevel@tonic-gate options->hostkeyalgorithms = xstrdup(arg); 6360Sstevel@tonic-gate break; 6370Sstevel@tonic-gate 6380Sstevel@tonic-gate case oProtocol: 6390Sstevel@tonic-gate intptr = &options->protocol; 6400Sstevel@tonic-gate arg = strdelim(&s); 6410Sstevel@tonic-gate if (!arg || *arg == '\0') 6420Sstevel@tonic-gate fatal("%.200s line %d: Missing argument.", filename, linenum); 6430Sstevel@tonic-gate value = proto_spec(arg); 6440Sstevel@tonic-gate if (value == SSH_PROTO_UNKNOWN) 6450Sstevel@tonic-gate fatal("%.200s line %d: Bad protocol spec '%s'.", 6460Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 6470Sstevel@tonic-gate if (*activep && *intptr == SSH_PROTO_UNKNOWN) 6480Sstevel@tonic-gate *intptr = value; 6490Sstevel@tonic-gate break; 6500Sstevel@tonic-gate 6510Sstevel@tonic-gate case oLogLevel: 6520Sstevel@tonic-gate intptr = (int *) &options->log_level; 6530Sstevel@tonic-gate arg = strdelim(&s); 6540Sstevel@tonic-gate value = log_level_number(arg); 6550Sstevel@tonic-gate if (value == SYSLOG_LEVEL_NOT_SET) 6560Sstevel@tonic-gate fatal("%.200s line %d: unsupported log level '%s'", 6570Sstevel@tonic-gate filename, linenum, arg ? arg : "<NONE>"); 6580Sstevel@tonic-gate if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET) 6590Sstevel@tonic-gate *intptr = (LogLevel) value; 6600Sstevel@tonic-gate break; 6610Sstevel@tonic-gate 6620Sstevel@tonic-gate case oLocalForward: 6630Sstevel@tonic-gate case oRemoteForward: 6640Sstevel@tonic-gate arg = strdelim(&s); 6650Sstevel@tonic-gate if (!arg || *arg == '\0') 6660Sstevel@tonic-gate fatal("%.200s line %d: Missing port argument.", 6670Sstevel@tonic-gate filename, linenum); 6680Sstevel@tonic-gate if ((fwd_port = a2port(arg)) == 0) 6690Sstevel@tonic-gate fatal("%.200s line %d: Bad listen port.", 6700Sstevel@tonic-gate filename, linenum); 6710Sstevel@tonic-gate arg = strdelim(&s); 6720Sstevel@tonic-gate if (!arg || *arg == '\0') 6730Sstevel@tonic-gate fatal("%.200s line %d: Missing second argument.", 6740Sstevel@tonic-gate filename, linenum); 6750Sstevel@tonic-gate if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && 6760Sstevel@tonic-gate sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2) 6770Sstevel@tonic-gate fatal("%.200s line %d: Bad forwarding specification.", 6780Sstevel@tonic-gate filename, linenum); 6790Sstevel@tonic-gate if ((fwd_host_port = a2port(sfwd_host_port)) == 0) 6800Sstevel@tonic-gate fatal("%.200s line %d: Bad forwarding port.", 6810Sstevel@tonic-gate filename, linenum); 6820Sstevel@tonic-gate if (*activep) { 6830Sstevel@tonic-gate if (opcode == oLocalForward) 6840Sstevel@tonic-gate add_local_forward(options, fwd_port, buf, 6850Sstevel@tonic-gate fwd_host_port); 6860Sstevel@tonic-gate else if (opcode == oRemoteForward) 6870Sstevel@tonic-gate add_remote_forward(options, fwd_port, buf, 6880Sstevel@tonic-gate fwd_host_port); 6890Sstevel@tonic-gate } 6900Sstevel@tonic-gate break; 6910Sstevel@tonic-gate 6920Sstevel@tonic-gate case oDynamicForward: 6930Sstevel@tonic-gate arg = strdelim(&s); 6940Sstevel@tonic-gate if (!arg || *arg == '\0') 6950Sstevel@tonic-gate fatal("%.200s line %d: Missing port argument.", 6960Sstevel@tonic-gate filename, linenum); 6970Sstevel@tonic-gate fwd_port = a2port(arg); 6980Sstevel@tonic-gate if (fwd_port == 0) 6990Sstevel@tonic-gate fatal("%.200s line %d: Badly formatted port number.", 7000Sstevel@tonic-gate filename, linenum); 7010Sstevel@tonic-gate if (*activep) 7020Sstevel@tonic-gate add_local_forward(options, fwd_port, "socks4", 0); 7030Sstevel@tonic-gate break; 7040Sstevel@tonic-gate 7050Sstevel@tonic-gate case oClearAllForwardings: 7060Sstevel@tonic-gate intptr = &options->clear_forwardings; 7070Sstevel@tonic-gate goto parse_flag; 7080Sstevel@tonic-gate 7090Sstevel@tonic-gate case oHost: 7100Sstevel@tonic-gate *activep = 0; 7110Sstevel@tonic-gate while ((arg = strdelim(&s)) != NULL && *arg != '\0') 7120Sstevel@tonic-gate if (match_pattern(host, arg)) { 7130Sstevel@tonic-gate debug("Applying options for %.100s", arg); 7140Sstevel@tonic-gate *activep = 1; 7150Sstevel@tonic-gate break; 7160Sstevel@tonic-gate } 7170Sstevel@tonic-gate /* Avoid garbage check below, as strdelim is done. */ 7180Sstevel@tonic-gate return 0; 7190Sstevel@tonic-gate 7200Sstevel@tonic-gate case oEscapeChar: 7210Sstevel@tonic-gate intptr = &options->escape_char; 7220Sstevel@tonic-gate arg = strdelim(&s); 7230Sstevel@tonic-gate if (!arg || *arg == '\0') 7240Sstevel@tonic-gate fatal("%.200s line %d: Missing argument.", filename, linenum); 7250Sstevel@tonic-gate if (arg[0] == '^' && arg[2] == 0 && 7260Sstevel@tonic-gate (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 7270Sstevel@tonic-gate value = (u_char) arg[1] & 31; 7280Sstevel@tonic-gate else if (strlen(arg) == 1) 7290Sstevel@tonic-gate value = (u_char) arg[0]; 7300Sstevel@tonic-gate else if (strcmp(arg, "none") == 0) 7310Sstevel@tonic-gate value = SSH_ESCAPECHAR_NONE; 7320Sstevel@tonic-gate else { 7330Sstevel@tonic-gate fatal("%.200s line %d: Bad escape character.", 7340Sstevel@tonic-gate filename, linenum); 7350Sstevel@tonic-gate /* NOTREACHED */ 7360Sstevel@tonic-gate value = 0; /* Avoid compiler warning. */ 7370Sstevel@tonic-gate } 7380Sstevel@tonic-gate if (*activep && *intptr == -1) 7390Sstevel@tonic-gate *intptr = value; 7400Sstevel@tonic-gate break; 7410Sstevel@tonic-gate 7420Sstevel@tonic-gate case oDeprecated: 7430Sstevel@tonic-gate debug("%s line %d: Deprecated option \"%s\"", 7440Sstevel@tonic-gate filename, linenum, keyword); 7450Sstevel@tonic-gate return 0; 7460Sstevel@tonic-gate 7470Sstevel@tonic-gate default: 7480Sstevel@tonic-gate fatal("process_config_line: Unimplemented opcode %d", opcode); 7490Sstevel@tonic-gate } 7500Sstevel@tonic-gate 7510Sstevel@tonic-gate /* Check that there is no garbage at end of line. */ 7520Sstevel@tonic-gate if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 7530Sstevel@tonic-gate fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 7540Sstevel@tonic-gate filename, linenum, arg); 7550Sstevel@tonic-gate } 7560Sstevel@tonic-gate return 0; 7570Sstevel@tonic-gate } 7580Sstevel@tonic-gate 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate /* 7610Sstevel@tonic-gate * Reads the config file and modifies the options accordingly. Options 7620Sstevel@tonic-gate * should already be initialized before this call. This never returns if 7630Sstevel@tonic-gate * there is an error. If the file does not exist, this returns 0. 7640Sstevel@tonic-gate */ 7650Sstevel@tonic-gate 7660Sstevel@tonic-gate int 7670Sstevel@tonic-gate read_config_file(const char *filename, const char *host, Options *options) 7680Sstevel@tonic-gate { 7690Sstevel@tonic-gate FILE *f; 7700Sstevel@tonic-gate char line[1024]; 7710Sstevel@tonic-gate int active, linenum; 7720Sstevel@tonic-gate int bad_options = 0; 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate /* Open the file. */ 7750Sstevel@tonic-gate f = fopen(filename, "r"); 7760Sstevel@tonic-gate if (!f) 7770Sstevel@tonic-gate return 0; 7780Sstevel@tonic-gate 7790Sstevel@tonic-gate debug("Reading configuration data %.200s", filename); 7800Sstevel@tonic-gate 7810Sstevel@tonic-gate /* 7820Sstevel@tonic-gate * Mark that we are now processing the options. This flag is turned 7830Sstevel@tonic-gate * on/off by Host specifications. 7840Sstevel@tonic-gate */ 7850Sstevel@tonic-gate active = 1; 7860Sstevel@tonic-gate linenum = 0; 7870Sstevel@tonic-gate while (fgets(line, sizeof(line), f)) { 7880Sstevel@tonic-gate /* Update line number counter. */ 7890Sstevel@tonic-gate linenum++; 7900Sstevel@tonic-gate if (process_config_line(options, host, line, filename, linenum, &active) != 0) 7910Sstevel@tonic-gate bad_options++; 7920Sstevel@tonic-gate } 7930Sstevel@tonic-gate fclose(f); 7940Sstevel@tonic-gate if (bad_options > 0) 7950Sstevel@tonic-gate fatal("%s: terminating, %d bad configuration options", 7960Sstevel@tonic-gate filename, bad_options); 7970Sstevel@tonic-gate return 1; 7980Sstevel@tonic-gate } 7990Sstevel@tonic-gate 8000Sstevel@tonic-gate /* 8010Sstevel@tonic-gate * Initializes options to special values that indicate that they have not yet 8020Sstevel@tonic-gate * been set. Read_config_file will only set options with this value. Options 8030Sstevel@tonic-gate * are processed in the following order: command line, user config file, 8040Sstevel@tonic-gate * system config file. Last, fill_default_options is called. 8050Sstevel@tonic-gate */ 8060Sstevel@tonic-gate 8070Sstevel@tonic-gate void 8080Sstevel@tonic-gate initialize_options(Options * options) 8090Sstevel@tonic-gate { 8100Sstevel@tonic-gate memset(options, 'X', sizeof(*options)); 8110Sstevel@tonic-gate options->forward_agent = -1; 8120Sstevel@tonic-gate options->forward_x11 = -1; 8130Sstevel@tonic-gate options->xauth_location = NULL; 8140Sstevel@tonic-gate options->gateway_ports = -1; 8150Sstevel@tonic-gate options->use_privileged_port = -1; 8160Sstevel@tonic-gate options->rhosts_authentication = -1; 8170Sstevel@tonic-gate options->rsa_authentication = -1; 8180Sstevel@tonic-gate options->pubkey_authentication = -1; 8190Sstevel@tonic-gate options->challenge_response_authentication = -1; 8200Sstevel@tonic-gate #ifdef GSSAPI 8210Sstevel@tonic-gate options->gss_keyex = -1; 8220Sstevel@tonic-gate options->gss_authentication = -1; 8230Sstevel@tonic-gate options->gss_deleg_creds = -1; 8240Sstevel@tonic-gate #ifdef GSI 8250Sstevel@tonic-gate options->gss_globus_deleg_limited_proxy = -1; 8260Sstevel@tonic-gate #endif /* GSI */ 8270Sstevel@tonic-gate #endif /* GSSAPI */ 8280Sstevel@tonic-gate 8290Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 8300Sstevel@tonic-gate options->kerberos_authentication = -1; 8310Sstevel@tonic-gate #endif 8320Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 8330Sstevel@tonic-gate options->kerberos_tgt_passing = -1; 8340Sstevel@tonic-gate #endif 8350Sstevel@tonic-gate #ifdef AFS 8360Sstevel@tonic-gate options->afs_token_passing = -1; 8370Sstevel@tonic-gate #endif 8380Sstevel@tonic-gate options->password_authentication = -1; 8390Sstevel@tonic-gate options->kbd_interactive_authentication = -1; 8400Sstevel@tonic-gate options->kbd_interactive_devices = NULL; 8410Sstevel@tonic-gate options->rhosts_rsa_authentication = -1; 8420Sstevel@tonic-gate options->hostbased_authentication = -1; 8430Sstevel@tonic-gate options->batch_mode = -1; 8440Sstevel@tonic-gate options->check_host_ip = -1; 8450Sstevel@tonic-gate options->strict_host_key_checking = -1; 8460Sstevel@tonic-gate options->compression = -1; 8470Sstevel@tonic-gate options->keepalives = -1; 8480Sstevel@tonic-gate options->compression_level = -1; 8490Sstevel@tonic-gate options->port = -1; 8500Sstevel@tonic-gate options->connection_attempts = -1; 8513946Sjp161948 options->connection_timeout = -1; 8520Sstevel@tonic-gate options->number_of_password_prompts = -1; 8530Sstevel@tonic-gate options->cipher = -1; 8540Sstevel@tonic-gate options->ciphers = NULL; 8550Sstevel@tonic-gate options->macs = NULL; 8560Sstevel@tonic-gate options->hostkeyalgorithms = NULL; 8570Sstevel@tonic-gate options->protocol = SSH_PROTO_UNKNOWN; 8580Sstevel@tonic-gate options->num_identity_files = 0; 8590Sstevel@tonic-gate options->hostname = NULL; 8600Sstevel@tonic-gate options->host_key_alias = NULL; 8610Sstevel@tonic-gate options->proxy_command = NULL; 8620Sstevel@tonic-gate options->user = NULL; 8630Sstevel@tonic-gate options->escape_char = -1; 8640Sstevel@tonic-gate options->system_hostfile = NULL; 8650Sstevel@tonic-gate options->user_hostfile = NULL; 8660Sstevel@tonic-gate options->system_hostfile2 = NULL; 8670Sstevel@tonic-gate options->user_hostfile2 = NULL; 8680Sstevel@tonic-gate options->num_local_forwards = 0; 8690Sstevel@tonic-gate options->num_remote_forwards = 0; 8700Sstevel@tonic-gate options->clear_forwardings = -1; 8710Sstevel@tonic-gate options->log_level = SYSLOG_LEVEL_NOT_SET; 8720Sstevel@tonic-gate options->preferred_authentications = NULL; 8730Sstevel@tonic-gate options->bind_address = NULL; 8740Sstevel@tonic-gate options->smartcard_device = NULL; 8750Sstevel@tonic-gate options->no_host_authentication_for_localhost = - 1; 8760Sstevel@tonic-gate options->fallback_to_rsh = -1; 8770Sstevel@tonic-gate options->use_rsh = -1; 8780Sstevel@tonic-gate } 8790Sstevel@tonic-gate 8800Sstevel@tonic-gate /* 8810Sstevel@tonic-gate * Called after processing other sources of option data, this fills those 8820Sstevel@tonic-gate * options for which no value has been specified with their default values. 8830Sstevel@tonic-gate */ 8840Sstevel@tonic-gate 8850Sstevel@tonic-gate void 8860Sstevel@tonic-gate fill_default_options(Options * options) 8870Sstevel@tonic-gate { 8880Sstevel@tonic-gate int len; 8890Sstevel@tonic-gate 8900Sstevel@tonic-gate if (options->forward_agent == -1) 8910Sstevel@tonic-gate options->forward_agent = 0; 8920Sstevel@tonic-gate if (options->forward_x11 == -1) 8930Sstevel@tonic-gate options->forward_x11 = 0; 8940Sstevel@tonic-gate if (options->xauth_location == NULL) 8950Sstevel@tonic-gate options->xauth_location = _PATH_XAUTH; 8960Sstevel@tonic-gate if (options->gateway_ports == -1) 8970Sstevel@tonic-gate options->gateway_ports = 0; 8980Sstevel@tonic-gate if (options->use_privileged_port == -1) 8990Sstevel@tonic-gate options->use_privileged_port = 0; 9000Sstevel@tonic-gate if (options->rhosts_authentication == -1) 9010Sstevel@tonic-gate options->rhosts_authentication = 0; 9020Sstevel@tonic-gate if (options->rsa_authentication == -1) 9030Sstevel@tonic-gate options->rsa_authentication = 1; 9040Sstevel@tonic-gate if (options->pubkey_authentication == -1) 9050Sstevel@tonic-gate options->pubkey_authentication = 1; 9060Sstevel@tonic-gate if (options->challenge_response_authentication == -1) 9070Sstevel@tonic-gate options->challenge_response_authentication = 1; 9080Sstevel@tonic-gate #ifdef GSSAPI 9090Sstevel@tonic-gate if (options->gss_keyex == -1) 9100Sstevel@tonic-gate options->gss_keyex = 1; 9110Sstevel@tonic-gate if (options->gss_authentication == -1) 9120Sstevel@tonic-gate options->gss_authentication = 1; 9130Sstevel@tonic-gate if (options->gss_deleg_creds == -1) 9140Sstevel@tonic-gate options->gss_deleg_creds = 0; 9150Sstevel@tonic-gate #ifdef GSI 9160Sstevel@tonic-gate if (options->gss_globus_deleg_limited_proxy == -1) 9170Sstevel@tonic-gate options->gss_globus_deleg_limited_proxy = 0; 9180Sstevel@tonic-gate #endif /* GSI */ 9190Sstevel@tonic-gate #endif /* GSSAPI */ 9200Sstevel@tonic-gate #if defined(KRB4) || defined(KRB5) 9210Sstevel@tonic-gate if (options->kerberos_authentication == -1) 9220Sstevel@tonic-gate options->kerberos_authentication = 1; 9230Sstevel@tonic-gate #endif 9240Sstevel@tonic-gate #if defined(AFS) || defined(KRB5) 9250Sstevel@tonic-gate if (options->kerberos_tgt_passing == -1) 9260Sstevel@tonic-gate options->kerberos_tgt_passing = 1; 9270Sstevel@tonic-gate #endif 9280Sstevel@tonic-gate #ifdef AFS 9290Sstevel@tonic-gate if (options->afs_token_passing == -1) 9300Sstevel@tonic-gate options->afs_token_passing = 1; 9310Sstevel@tonic-gate #endif 9320Sstevel@tonic-gate if (options->password_authentication == -1) 9330Sstevel@tonic-gate options->password_authentication = 1; 9340Sstevel@tonic-gate if (options->kbd_interactive_authentication == -1) 9350Sstevel@tonic-gate options->kbd_interactive_authentication = 1; 9360Sstevel@tonic-gate if (options->rhosts_rsa_authentication == -1) 9370Sstevel@tonic-gate options->rhosts_rsa_authentication = 0; 9380Sstevel@tonic-gate if (options->hostbased_authentication == -1) 9390Sstevel@tonic-gate options->hostbased_authentication = 0; 9400Sstevel@tonic-gate if (options->batch_mode == -1) 9410Sstevel@tonic-gate options->batch_mode = 0; 9420Sstevel@tonic-gate if (options->check_host_ip == -1) 9430Sstevel@tonic-gate options->check_host_ip = 1; 9440Sstevel@tonic-gate if (options->strict_host_key_checking == -1) 9450Sstevel@tonic-gate options->strict_host_key_checking = 2; /* 2 is default */ 9460Sstevel@tonic-gate if (options->compression == -1) 9470Sstevel@tonic-gate options->compression = 0; 9480Sstevel@tonic-gate if (options->keepalives == -1) 9490Sstevel@tonic-gate options->keepalives = 1; 9500Sstevel@tonic-gate if (options->compression_level == -1) 9510Sstevel@tonic-gate options->compression_level = 6; 9520Sstevel@tonic-gate if (options->port == -1) 9530Sstevel@tonic-gate options->port = 0; /* Filled in ssh_connect. */ 9540Sstevel@tonic-gate if (options->connection_attempts == -1) 9550Sstevel@tonic-gate options->connection_attempts = 1; 9560Sstevel@tonic-gate if (options->number_of_password_prompts == -1) 9570Sstevel@tonic-gate options->number_of_password_prompts = 3; 9580Sstevel@tonic-gate /* Selected in ssh_login(). */ 9590Sstevel@tonic-gate if (options->cipher == -1) 9600Sstevel@tonic-gate options->cipher = SSH_CIPHER_NOT_SET; 9610Sstevel@tonic-gate /* options->ciphers, default set in myproposals.h */ 9620Sstevel@tonic-gate /* options->macs, default set in myproposals.h */ 9630Sstevel@tonic-gate /* options->hostkeyalgorithms, default set in myproposals.h */ 9640Sstevel@tonic-gate if (options->protocol == SSH_PROTO_UNKNOWN) 9650Sstevel@tonic-gate options->protocol = SSH_PROTO_1|SSH_PROTO_2; 9660Sstevel@tonic-gate if (options->num_identity_files == 0) { 9670Sstevel@tonic-gate if (options->protocol & SSH_PROTO_1) { 9680Sstevel@tonic-gate len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 9690Sstevel@tonic-gate options->identity_files[options->num_identity_files] = 9700Sstevel@tonic-gate xmalloc(len); 9710Sstevel@tonic-gate snprintf(options->identity_files[options->num_identity_files++], 9720Sstevel@tonic-gate len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 9730Sstevel@tonic-gate } 9740Sstevel@tonic-gate if (options->protocol & SSH_PROTO_2) { 9750Sstevel@tonic-gate len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 9760Sstevel@tonic-gate options->identity_files[options->num_identity_files] = 9770Sstevel@tonic-gate xmalloc(len); 9780Sstevel@tonic-gate snprintf(options->identity_files[options->num_identity_files++], 9790Sstevel@tonic-gate len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 9800Sstevel@tonic-gate 9810Sstevel@tonic-gate len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 9820Sstevel@tonic-gate options->identity_files[options->num_identity_files] = 9830Sstevel@tonic-gate xmalloc(len); 9840Sstevel@tonic-gate snprintf(options->identity_files[options->num_identity_files++], 9850Sstevel@tonic-gate len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 9860Sstevel@tonic-gate } 9870Sstevel@tonic-gate } 9880Sstevel@tonic-gate if (options->escape_char == -1) 9890Sstevel@tonic-gate options->escape_char = '~'; 9900Sstevel@tonic-gate if (options->system_hostfile == NULL) 9910Sstevel@tonic-gate options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; 9920Sstevel@tonic-gate if (options->user_hostfile == NULL) 9930Sstevel@tonic-gate options->user_hostfile = _PATH_SSH_USER_HOSTFILE; 9940Sstevel@tonic-gate if (options->system_hostfile2 == NULL) 9950Sstevel@tonic-gate options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; 9960Sstevel@tonic-gate if (options->user_hostfile2 == NULL) 9970Sstevel@tonic-gate options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; 9980Sstevel@tonic-gate if (options->log_level == SYSLOG_LEVEL_NOT_SET) 9990Sstevel@tonic-gate options->log_level = SYSLOG_LEVEL_INFO; 10000Sstevel@tonic-gate if (options->clear_forwardings == 1) 10010Sstevel@tonic-gate clear_forwardings(options); 10020Sstevel@tonic-gate if (options->no_host_authentication_for_localhost == - 1) 10030Sstevel@tonic-gate options->no_host_authentication_for_localhost = 0; 10040Sstevel@tonic-gate if (options->fallback_to_rsh == - 1) 10050Sstevel@tonic-gate options->fallback_to_rsh = 0; 10060Sstevel@tonic-gate if (options->use_rsh == - 1) 10070Sstevel@tonic-gate options->use_rsh = 0; 10080Sstevel@tonic-gate /* options->proxy_command should not be set by default */ 10090Sstevel@tonic-gate /* options->user will be set in the main program if appropriate */ 10100Sstevel@tonic-gate /* options->hostname will be set in the main program if appropriate */ 10110Sstevel@tonic-gate /* options->host_key_alias should not be set by default */ 10120Sstevel@tonic-gate /* options->preferred_authentications will be set in ssh */ 10130Sstevel@tonic-gate } 1014