Annotation of src/usr.bin/ssh/readconf.c, Revision 1.150
1.1 deraadt 1: /*
1.18 deraadt 2: * Author: Tatu Ylonen <ylo@cs.hut.fi>
3: * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4: * All rights reserved
5: * Functions for reading the configuration files.
1.26 markus 6: *
1.46 deraadt 7: * As far as I am concerned, the code I have written for this software
8: * can be used freely for any purpose. Any derived versions of this
9: * software must be clearly marked as such, and if the derived work is
10: * incompatible with the protocol description in the RFC file, it must be
11: * called by a name other than "ssh" or "Secure Shell".
1.18 deraadt 12: */
1.1 deraadt 13:
14: #include "includes.h"
1.147 stevesk 15:
16: #include <sys/types.h>
17: #include <sys/stat.h>
1.148 stevesk 18:
19: #include <ctype.h>
1.1 deraadt 20:
21: #include "ssh.h"
22: #include "xmalloc.h"
1.25 markus 23: #include "compat.h"
1.58 markus 24: #include "cipher.h"
1.55 markus 25: #include "pathnames.h"
1.58 markus 26: #include "log.h"
27: #include "readconf.h"
28: #include "match.h"
29: #include "misc.h"
1.62 markus 30: #include "kex.h"
31: #include "mac.h"
1.1 deraadt 32:
33: /* Format of the configuration file:
34:
35: # Configuration data is parsed as follows:
36: # 1. command line options
37: # 2. user-specific file
38: # 3. system-wide file
39: # Any configuration value is only changed the first time it is set.
40: # Thus, host-specific definitions should be at the beginning of the
41: # configuration file, and defaults at the end.
42:
43: # Host-specific declarations. These may override anything above. A single
44: # host may match multiple declarations; these are processed in the order
45: # that they are given in.
46:
47: Host *.ngs.fi ngs.fi
1.96 markus 48: User foo
1.1 deraadt 49:
50: Host fake.com
51: HostName another.host.name.real.org
52: User blaah
53: Port 34289
54: ForwardX11 no
55: ForwardAgent no
56:
57: Host books.com
58: RemoteForward 9999 shadows.cs.hut.fi:9999
59: Cipher 3des
60:
61: Host fascist.blob.com
62: Port 23123
63: User tylonen
64: PasswordAuthentication no
65:
66: Host puukko.hut.fi
67: User t35124p
68: ProxyCommand ssh-proxy %h %p
69:
70: Host *.fr
1.96 markus 71: PublicKeyAuthentication no
1.1 deraadt 72:
73: Host *.su
74: Cipher none
75: PasswordAuthentication no
76:
1.144 reyk 77: Host vpn.fake.com
78: Tunnel yes
79: TunnelDevice 3
80:
1.1 deraadt 81: # Defaults for various options
82: Host *
83: ForwardAgent no
1.50 markus 84: ForwardX11 no
1.1 deraadt 85: PasswordAuthentication yes
86: RSAAuthentication yes
87: RhostsRSAAuthentication yes
88: StrictHostKeyChecking yes
1.126 markus 89: TcpKeepAlive no
1.1 deraadt 90: IdentityFile ~/.ssh/identity
91: Port 22
92: EscapeChar ~
93:
94: */
95:
96: /* Keyword tokens. */
97:
1.17 markus 98: typedef enum {
99: oBadOption,
1.123 markus 100: oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
1.100 deraadt 101: oPasswordAuthentication, oRSAAuthentication,
1.59 markus 102: oChallengeResponseAuthentication, oXAuthLocation,
1.17 markus 103: oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
104: oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
105: oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
106: oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
1.126 markus 107: oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
1.62 markus 108: oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
1.50 markus 109: oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
1.67 markus 110: oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
1.76 markus 111: oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
1.90 stevesk 112: oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
1.96 markus 113: oClearAllForwardings, oNoHostAuthenticationForLocalhost,
1.111 djm 114: oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
1.118 markus 115: oAddressFamily, oGssAuthentication, oGssDelegateCreds,
1.128 markus 116: oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
1.136 djm 117: oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
1.144 reyk 118: oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
1.110 jakob 119: oDeprecated, oUnsupported
1.1 deraadt 120: } OpCodes;
121:
122: /* Textual representations of the tokens. */
123:
1.17 markus 124: static struct {
125: const char *name;
126: OpCodes opcode;
127: } keywords[] = {
128: { "forwardagent", oForwardAgent },
129: { "forwardx11", oForwardX11 },
1.123 markus 130: { "forwardx11trusted", oForwardX11Trusted },
1.34 markus 131: { "xauthlocation", oXAuthLocation },
1.17 markus 132: { "gatewayports", oGatewayPorts },
133: { "useprivilegedport", oUsePrivilegedPort },
1.116 markus 134: { "rhostsauthentication", oDeprecated },
1.17 markus 135: { "passwordauthentication", oPasswordAuthentication },
1.48 markus 136: { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
137: { "kbdinteractivedevices", oKbdInteractiveDevices },
1.17 markus 138: { "rsaauthentication", oRSAAuthentication },
1.50 markus 139: { "pubkeyauthentication", oPubkeyAuthentication },
1.59 markus 140: { "dsaauthentication", oPubkeyAuthentication }, /* alias */
1.72 markus 141: { "rhostsrsaauthentication", oRhostsRSAAuthentication },
1.73 markus 142: { "hostbasedauthentication", oHostbasedAuthentication },
1.59 markus 143: { "challengeresponseauthentication", oChallengeResponseAuthentication },
144: { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
145: { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
1.110 jakob 146: { "kerberosauthentication", oUnsupported },
147: { "kerberostgtpassing", oUnsupported },
148: { "afstokenpassing", oUnsupported },
1.118 markus 149: #if defined(GSSAPI)
150: { "gssapiauthentication", oGssAuthentication },
151: { "gssapidelegatecredentials", oGssDelegateCreds },
152: #else
153: { "gssapiauthentication", oUnsupported },
154: { "gssapidelegatecredentials", oUnsupported },
155: #endif
1.96 markus 156: { "fallbacktorsh", oDeprecated },
157: { "usersh", oDeprecated },
1.17 markus 158: { "identityfile", oIdentityFile },
1.50 markus 159: { "identityfile2", oIdentityFile }, /* alias */
1.128 markus 160: { "identitiesonly", oIdentitiesOnly },
1.17 markus 161: { "hostname", oHostName },
1.52 markus 162: { "hostkeyalias", oHostKeyAlias },
1.17 markus 163: { "proxycommand", oProxyCommand },
164: { "port", oPort },
165: { "cipher", oCipher },
1.25 markus 166: { "ciphers", oCiphers },
1.62 markus 167: { "macs", oMacs },
1.25 markus 168: { "protocol", oProtocol },
1.17 markus 169: { "remoteforward", oRemoteForward },
170: { "localforward", oLocalForward },
171: { "user", oUser },
172: { "host", oHost },
173: { "escapechar", oEscapeChar },
174: { "globalknownhostsfile", oGlobalKnownHostsFile },
1.81 markus 175: { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */
1.27 markus 176: { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
1.81 markus 177: { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */
1.17 markus 178: { "connectionattempts", oConnectionAttempts },
179: { "batchmode", oBatchMode },
180: { "checkhostip", oCheckHostIP },
181: { "stricthostkeychecking", oStrictHostKeyChecking },
182: { "compression", oCompression },
183: { "compressionlevel", oCompressionLevel },
1.126 markus 184: { "tcpkeepalive", oTCPKeepAlive },
185: { "keepalive", oTCPKeepAlive }, /* obsolete */
1.17 markus 186: { "numberofpasswordprompts", oNumberOfPasswordPrompts },
187: { "loglevel", oLogLevel },
1.71 markus 188: { "dynamicforward", oDynamicForward },
1.67 markus 189: { "preferredauthentications", oPreferredAuthentications },
1.76 markus 190: { "hostkeyalgorithms", oHostKeyAlgorithms },
1.77 markus 191: { "bindaddress", oBindAddress },
1.110 jakob 192: #ifdef SMARTCARD
1.85 jakob 193: { "smartcarddevice", oSmartcardDevice },
1.110 jakob 194: #else
195: { "smartcarddevice", oUnsupported },
196: #endif
1.93 deraadt 197: { "clearallforwardings", oClearAllForwardings },
1.101 markus 198: { "enablesshkeysign", oEnableSSHKeysign },
1.107 jakob 199: { "verifyhostkeydns", oVerifyHostKeyDNS },
1.93 deraadt 200: { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
1.105 markus 201: { "rekeylimit", oRekeyLimit },
1.111 djm 202: { "connecttimeout", oConnectTimeout },
1.112 djm 203: { "addressfamily", oAddressFamily },
1.127 markus 204: { "serveraliveinterval", oServerAliveInterval },
205: { "serveralivecountmax", oServerAliveCountMax },
1.130 djm 206: { "sendenv", oSendEnv },
1.132 djm 207: { "controlpath", oControlPath },
208: { "controlmaster", oControlMaster },
1.136 djm 209: { "hashknownhosts", oHashKnownHosts },
1.144 reyk 210: { "tunnel", oTunnel },
211: { "tunneldevice", oTunnelDevice },
212: { "localcommand", oLocalCommand },
213: { "permitlocalcommand", oPermitLocalCommand },
1.92 stevesk 214: { NULL, oBadOption }
1.13 markus 215: };
216:
1.19 markus 217: /*
218: * Adds a local TCP/IP port forward to options. Never returns if there is an
219: * error.
220: */
1.1 deraadt 221:
1.26 markus 222: void
1.135 djm 223: add_local_forward(Options *options, const Forward *newfwd)
1.1 deraadt 224: {
1.17 markus 225: Forward *fwd;
226: extern uid_t original_real_uid;
1.135 djm 227: if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
1.64 millert 228: fatal("Privileged ports can only be forwarded by root.");
1.17 markus 229: if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
230: fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
231: fwd = &options->local_forwards[options->num_local_forwards++];
1.135 djm 232:
233: fwd->listen_host = (newfwd->listen_host == NULL) ?
234: NULL : xstrdup(newfwd->listen_host);
235: fwd->listen_port = newfwd->listen_port;
236: fwd->connect_host = xstrdup(newfwd->connect_host);
237: fwd->connect_port = newfwd->connect_port;
1.1 deraadt 238: }
239:
1.19 markus 240: /*
241: * Adds a remote TCP/IP port forward to options. Never returns if there is
242: * an error.
243: */
1.1 deraadt 244:
1.26 markus 245: void
1.135 djm 246: add_remote_forward(Options *options, const Forward *newfwd)
1.1 deraadt 247: {
1.17 markus 248: Forward *fwd;
249: if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
250: fatal("Too many remote forwards (max %d).",
1.93 deraadt 251: SSH_MAX_FORWARDS_PER_DIRECTION);
1.17 markus 252: fwd = &options->remote_forwards[options->num_remote_forwards++];
1.135 djm 253:
254: fwd->listen_host = (newfwd->listen_host == NULL) ?
255: NULL : xstrdup(newfwd->listen_host);
256: fwd->listen_port = newfwd->listen_port;
257: fwd->connect_host = xstrdup(newfwd->connect_host);
258: fwd->connect_port = newfwd->connect_port;
1.1 deraadt 259: }
260:
1.90 stevesk 261: static void
262: clear_forwardings(Options *options)
263: {
264: int i;
265:
1.135 djm 266: for (i = 0; i < options->num_local_forwards; i++) {
1.138 dtucker 267: if (options->local_forwards[i].listen_host != NULL)
268: xfree(options->local_forwards[i].listen_host);
1.135 djm 269: xfree(options->local_forwards[i].connect_host);
270: }
1.90 stevesk 271: options->num_local_forwards = 0;
1.135 djm 272: for (i = 0; i < options->num_remote_forwards; i++) {
1.138 dtucker 273: if (options->remote_forwards[i].listen_host != NULL)
274: xfree(options->remote_forwards[i].listen_host);
1.135 djm 275: xfree(options->remote_forwards[i].connect_host);
276: }
1.90 stevesk 277: options->num_remote_forwards = 0;
1.145 reyk 278: options->tun_open = SSH_TUNMODE_NO;
1.90 stevesk 279: }
280:
1.19 markus 281: /*
1.70 stevesk 282: * Returns the number of the token pointed to by cp or oBadOption.
1.19 markus 283: */
1.1 deraadt 284:
1.26 markus 285: static OpCodes
1.17 markus 286: parse_token(const char *cp, const char *filename, int linenum)
1.1 deraadt 287: {
1.51 markus 288: u_int i;
1.1 deraadt 289:
1.17 markus 290: for (i = 0; keywords[i].name; i++)
1.20 markus 291: if (strcasecmp(cp, keywords[i].name) == 0)
1.17 markus 292: return keywords[i].opcode;
293:
1.75 stevesk 294: error("%s: line %d: Bad configuration option: %s",
295: filename, linenum, cp);
1.17 markus 296: return oBadOption;
1.1 deraadt 297: }
298:
1.19 markus 299: /*
300: * Processes a single option line as used in the configuration files. This
301: * only sets those values that have not already been set.
302: */
1.102 markus 303: #define WHITESPACE " \t\r\n"
1.1 deraadt 304:
1.14 markus 305: int
306: process_config_line(Options *options, const char *host,
1.17 markus 307: char *line, const char *filename, int linenum,
308: int *activep)
1.1 deraadt 309: {
1.135 djm 310: char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
1.146 djm 311: int opcode, *intptr, value, value2, scale;
312: long long orig, val64;
1.102 markus 313: size_t len;
1.135 djm 314: Forward fwd;
1.106 djm 315:
316: /* Strip trailing whitespace */
1.139 deraadt 317: for (len = strlen(line) - 1; len > 0; len--) {
1.106 djm 318: if (strchr(WHITESPACE, line[len]) == NULL)
319: break;
320: line[len] = '\0';
321: }
1.1 deraadt 322:
1.42 provos 323: s = line;
324: /* Get the keyword. (Each line is supposed to begin with a keyword). */
1.149 djm 325: if ((keyword = strdelim(&s)) == NULL)
326: return 0;
1.42 provos 327: /* Ignore leading whitespace. */
328: if (*keyword == '\0')
1.43 markus 329: keyword = strdelim(&s);
1.56 deraadt 330: if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
1.17 markus 331: return 0;
332:
1.38 provos 333: opcode = parse_token(keyword, filename, linenum);
1.17 markus 334:
335: switch (opcode) {
336: case oBadOption:
1.19 markus 337: /* don't panic, but count bad options */
338: return -1;
1.17 markus 339: /* NOTREACHED */
1.111 djm 340: case oConnectTimeout:
341: intptr = &options->connection_timeout;
1.127 markus 342: parse_time:
1.111 djm 343: arg = strdelim(&s);
344: if (!arg || *arg == '\0')
345: fatal("%s line %d: missing time value.",
346: filename, linenum);
347: if ((value = convtime(arg)) == -1)
348: fatal("%s line %d: invalid time value.",
349: filename, linenum);
350: if (*intptr == -1)
351: *intptr = value;
352: break;
353:
1.17 markus 354: case oForwardAgent:
355: intptr = &options->forward_agent;
356: parse_flag:
1.42 provos 357: arg = strdelim(&s);
1.40 ho 358: if (!arg || *arg == '\0')
1.17 markus 359: fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
360: value = 0; /* To avoid compiler warning... */
1.38 provos 361: if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1.17 markus 362: value = 1;
1.38 provos 363: else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1.17 markus 364: value = 0;
365: else
366: fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
367: if (*activep && *intptr == -1)
368: *intptr = value;
369: break;
370:
371: case oForwardX11:
372: intptr = &options->forward_x11;
373: goto parse_flag;
374:
1.123 markus 375: case oForwardX11Trusted:
376: intptr = &options->forward_x11_trusted;
377: goto parse_flag;
378:
1.17 markus 379: case oGatewayPorts:
380: intptr = &options->gateway_ports;
381: goto parse_flag;
382:
383: case oUsePrivilegedPort:
384: intptr = &options->use_privileged_port;
385: goto parse_flag;
386:
387: case oPasswordAuthentication:
388: intptr = &options->password_authentication;
389: goto parse_flag;
390:
1.48 markus 391: case oKbdInteractiveAuthentication:
392: intptr = &options->kbd_interactive_authentication;
393: goto parse_flag;
394:
395: case oKbdInteractiveDevices:
396: charptr = &options->kbd_interactive_devices;
397: goto parse_string;
398:
1.50 markus 399: case oPubkeyAuthentication:
400: intptr = &options->pubkey_authentication;
1.30 markus 401: goto parse_flag;
402:
1.17 markus 403: case oRSAAuthentication:
404: intptr = &options->rsa_authentication;
405: goto parse_flag;
406:
407: case oRhostsRSAAuthentication:
408: intptr = &options->rhosts_rsa_authentication;
409: goto parse_flag;
410:
1.72 markus 411: case oHostbasedAuthentication:
412: intptr = &options->hostbased_authentication;
413: goto parse_flag;
414:
1.59 markus 415: case oChallengeResponseAuthentication:
1.78 markus 416: intptr = &options->challenge_response_authentication;
1.17 markus 417: goto parse_flag;
1.108 jakob 418:
1.118 markus 419: case oGssAuthentication:
420: intptr = &options->gss_authentication;
421: goto parse_flag;
422:
423: case oGssDelegateCreds:
424: intptr = &options->gss_deleg_creds;
425: goto parse_flag;
426:
1.17 markus 427: case oBatchMode:
428: intptr = &options->batch_mode;
429: goto parse_flag;
430:
431: case oCheckHostIP:
432: intptr = &options->check_host_ip;
433: goto parse_flag;
434:
1.107 jakob 435: case oVerifyHostKeyDNS:
436: intptr = &options->verify_host_key_dns;
1.125 jakob 437: goto parse_yesnoask;
1.107 jakob 438:
1.17 markus 439: case oStrictHostKeyChecking:
440: intptr = &options->strict_host_key_checking;
1.125 jakob 441: parse_yesnoask:
1.42 provos 442: arg = strdelim(&s);
1.40 ho 443: if (!arg || *arg == '\0')
1.60 stevesk 444: fatal("%.200s line %d: Missing yes/no/ask argument.",
1.93 deraadt 445: filename, linenum);
1.17 markus 446: value = 0; /* To avoid compiler warning... */
1.38 provos 447: if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1.17 markus 448: value = 1;
1.38 provos 449: else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1.17 markus 450: value = 0;
1.38 provos 451: else if (strcmp(arg, "ask") == 0)
1.17 markus 452: value = 2;
453: else
454: fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
455: if (*activep && *intptr == -1)
456: *intptr = value;
457: break;
458:
459: case oCompression:
460: intptr = &options->compression;
461: goto parse_flag;
462:
1.126 markus 463: case oTCPKeepAlive:
464: intptr = &options->tcp_keep_alive;
1.17 markus 465: goto parse_flag;
466:
1.91 markus 467: case oNoHostAuthenticationForLocalhost:
468: intptr = &options->no_host_authentication_for_localhost;
469: goto parse_flag;
470:
1.17 markus 471: case oNumberOfPasswordPrompts:
472: intptr = &options->number_of_password_prompts;
473: goto parse_int;
474:
475: case oCompressionLevel:
476: intptr = &options->compression_level;
477: goto parse_int;
478:
1.105 markus 479: case oRekeyLimit:
480: intptr = &options->rekey_limit;
481: arg = strdelim(&s);
482: if (!arg || *arg == '\0')
483: fatal("%.200s line %d: Missing argument.", filename, linenum);
484: if (arg[0] < '0' || arg[0] > '9')
485: fatal("%.200s line %d: Bad number.", filename, linenum);
1.146 djm 486: orig = val64 = strtoll(arg, &endofnumber, 10);
1.105 markus 487: if (arg == endofnumber)
488: fatal("%.200s line %d: Bad number.", filename, linenum);
489: switch (toupper(*endofnumber)) {
1.146 djm 490: case '\0':
491: scale = 1;
492: break;
1.105 markus 493: case 'K':
1.146 djm 494: scale = 1<<10;
1.105 markus 495: break;
496: case 'M':
1.146 djm 497: scale = 1<<20;
1.105 markus 498: break;
499: case 'G':
1.146 djm 500: scale = 1<<30;
1.105 markus 501: break;
1.146 djm 502: default:
503: fatal("%.200s line %d: Invalid RekeyLimit suffix",
504: filename, linenum);
1.105 markus 505: }
1.146 djm 506: val64 *= scale;
507: /* detect integer wrap and too-large limits */
508: if ((val64 / scale) != orig || val64 > INT_MAX)
509: fatal("%.200s line %d: RekeyLimit too large",
510: filename, linenum);
511: if (val64 < 16)
512: fatal("%.200s line %d: RekeyLimit too small",
513: filename, linenum);
1.105 markus 514: if (*activep && *intptr == -1)
1.146 djm 515: *intptr = (int)val64;
1.105 markus 516: break;
517:
1.17 markus 518: case oIdentityFile:
1.42 provos 519: arg = strdelim(&s);
1.40 ho 520: if (!arg || *arg == '\0')
1.17 markus 521: fatal("%.200s line %d: Missing argument.", filename, linenum);
522: if (*activep) {
1.50 markus 523: intptr = &options->num_identity_files;
1.27 markus 524: if (*intptr >= SSH_MAX_IDENTITY_FILES)
1.17 markus 525: fatal("%.200s line %d: Too many identity files specified (max %d).",
1.93 deraadt 526: filename, linenum, SSH_MAX_IDENTITY_FILES);
1.50 markus 527: charptr = &options->identity_files[*intptr];
1.38 provos 528: *charptr = xstrdup(arg);
1.27 markus 529: *intptr = *intptr + 1;
1.17 markus 530: }
531: break;
532:
1.34 markus 533: case oXAuthLocation:
534: charptr=&options->xauth_location;
535: goto parse_string;
536:
1.17 markus 537: case oUser:
538: charptr = &options->user;
539: parse_string:
1.42 provos 540: arg = strdelim(&s);
1.40 ho 541: if (!arg || *arg == '\0')
1.17 markus 542: fatal("%.200s line %d: Missing argument.", filename, linenum);
543: if (*activep && *charptr == NULL)
1.38 provos 544: *charptr = xstrdup(arg);
1.17 markus 545: break;
546:
547: case oGlobalKnownHostsFile:
548: charptr = &options->system_hostfile;
549: goto parse_string;
550:
551: case oUserKnownHostsFile:
552: charptr = &options->user_hostfile;
553: goto parse_string;
554:
1.27 markus 555: case oGlobalKnownHostsFile2:
556: charptr = &options->system_hostfile2;
557: goto parse_string;
558:
559: case oUserKnownHostsFile2:
560: charptr = &options->user_hostfile2;
561: goto parse_string;
562:
1.17 markus 563: case oHostName:
564: charptr = &options->hostname;
565: goto parse_string;
566:
1.52 markus 567: case oHostKeyAlias:
568: charptr = &options->host_key_alias;
569: goto parse_string;
570:
1.67 markus 571: case oPreferredAuthentications:
572: charptr = &options->preferred_authentications;
573: goto parse_string;
574:
1.77 markus 575: case oBindAddress:
576: charptr = &options->bind_address;
577: goto parse_string;
578:
1.85 jakob 579: case oSmartcardDevice:
1.86 markus 580: charptr = &options->smartcard_device;
581: goto parse_string;
1.85 jakob 582:
1.17 markus 583: case oProxyCommand:
1.144 reyk 584: charptr = &options->proxy_command;
585: parse_command:
1.113 markus 586: if (s == NULL)
587: fatal("%.200s line %d: Missing argument.", filename, linenum);
1.102 markus 588: len = strspn(s, WHITESPACE "=");
1.17 markus 589: if (*activep && *charptr == NULL)
1.102 markus 590: *charptr = xstrdup(s + len);
1.17 markus 591: return 0;
592:
593: case oPort:
594: intptr = &options->port;
595: parse_int:
1.42 provos 596: arg = strdelim(&s);
1.40 ho 597: if (!arg || *arg == '\0')
1.17 markus 598: fatal("%.200s line %d: Missing argument.", filename, linenum);
1.38 provos 599: if (arg[0] < '0' || arg[0] > '9')
1.17 markus 600: fatal("%.200s line %d: Bad number.", filename, linenum);
1.21 markus 601:
602: /* Octal, decimal, or hex format? */
1.38 provos 603: value = strtol(arg, &endofnumber, 0);
604: if (arg == endofnumber)
1.21 markus 605: fatal("%.200s line %d: Bad number.", filename, linenum);
1.17 markus 606: if (*activep && *intptr == -1)
607: *intptr = value;
608: break;
609:
610: case oConnectionAttempts:
611: intptr = &options->connection_attempts;
612: goto parse_int;
613:
614: case oCipher:
615: intptr = &options->cipher;
1.42 provos 616: arg = strdelim(&s);
1.40 ho 617: if (!arg || *arg == '\0')
1.32 markus 618: fatal("%.200s line %d: Missing argument.", filename, linenum);
1.38 provos 619: value = cipher_number(arg);
1.17 markus 620: if (value == -1)
621: fatal("%.200s line %d: Bad cipher '%s'.",
1.93 deraadt 622: filename, linenum, arg ? arg : "<NONE>");
1.17 markus 623: if (*activep && *intptr == -1)
624: *intptr = value;
625: break;
626:
1.25 markus 627: case oCiphers:
1.42 provos 628: arg = strdelim(&s);
1.40 ho 629: if (!arg || *arg == '\0')
1.32 markus 630: fatal("%.200s line %d: Missing argument.", filename, linenum);
1.38 provos 631: if (!ciphers_valid(arg))
1.31 markus 632: fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1.93 deraadt 633: filename, linenum, arg ? arg : "<NONE>");
1.25 markus 634: if (*activep && options->ciphers == NULL)
1.38 provos 635: options->ciphers = xstrdup(arg);
1.25 markus 636: break;
637:
1.62 markus 638: case oMacs:
639: arg = strdelim(&s);
640: if (!arg || *arg == '\0')
641: fatal("%.200s line %d: Missing argument.", filename, linenum);
642: if (!mac_valid(arg))
643: fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1.93 deraadt 644: filename, linenum, arg ? arg : "<NONE>");
1.62 markus 645: if (*activep && options->macs == NULL)
646: options->macs = xstrdup(arg);
647: break;
648:
1.76 markus 649: case oHostKeyAlgorithms:
650: arg = strdelim(&s);
651: if (!arg || *arg == '\0')
652: fatal("%.200s line %d: Missing argument.", filename, linenum);
653: if (!key_names_valid2(arg))
654: fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
1.93 deraadt 655: filename, linenum, arg ? arg : "<NONE>");
1.76 markus 656: if (*activep && options->hostkeyalgorithms == NULL)
657: options->hostkeyalgorithms = xstrdup(arg);
658: break;
659:
1.25 markus 660: case oProtocol:
661: intptr = &options->protocol;
1.42 provos 662: arg = strdelim(&s);
1.40 ho 663: if (!arg || *arg == '\0')
1.32 markus 664: fatal("%.200s line %d: Missing argument.", filename, linenum);
1.38 provos 665: value = proto_spec(arg);
1.25 markus 666: if (value == SSH_PROTO_UNKNOWN)
667: fatal("%.200s line %d: Bad protocol spec '%s'.",
1.93 deraadt 668: filename, linenum, arg ? arg : "<NONE>");
1.25 markus 669: if (*activep && *intptr == SSH_PROTO_UNKNOWN)
670: *intptr = value;
671: break;
672:
1.17 markus 673: case oLogLevel:
674: intptr = (int *) &options->log_level;
1.42 provos 675: arg = strdelim(&s);
1.38 provos 676: value = log_level_number(arg);
1.95 markus 677: if (value == SYSLOG_LEVEL_NOT_SET)
1.64 millert 678: fatal("%.200s line %d: unsupported log level '%s'",
1.93 deraadt 679: filename, linenum, arg ? arg : "<NONE>");
1.95 markus 680: if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
1.17 markus 681: *intptr = (LogLevel) value;
682: break;
683:
1.88 stevesk 684: case oLocalForward:
1.17 markus 685: case oRemoteForward:
1.42 provos 686: arg = strdelim(&s);
1.135 djm 687: if (arg == NULL || *arg == '\0')
1.88 stevesk 688: fatal("%.200s line %d: Missing port argument.",
689: filename, linenum);
1.135 djm 690: arg2 = strdelim(&s);
691: if (arg2 == NULL || *arg2 == '\0')
692: fatal("%.200s line %d: Missing target argument.",
1.88 stevesk 693: filename, linenum);
1.135 djm 694:
695: /* construct a string for parse_forward */
696: snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
697:
698: if (parse_forward(&fwd, fwdarg) == 0)
1.88 stevesk 699: fatal("%.200s line %d: Bad forwarding specification.",
700: filename, linenum);
1.135 djm 701:
1.88 stevesk 702: if (*activep) {
703: if (opcode == oLocalForward)
1.135 djm 704: add_local_forward(options, &fwd);
1.88 stevesk 705: else if (opcode == oRemoteForward)
1.135 djm 706: add_remote_forward(options, &fwd);
1.88 stevesk 707: }
1.17 markus 708: break;
1.71 markus 709:
710: case oDynamicForward:
711: arg = strdelim(&s);
712: if (!arg || *arg == '\0')
713: fatal("%.200s line %d: Missing port argument.",
714: filename, linenum);
1.135 djm 715: memset(&fwd, '\0', sizeof(fwd));
716: fwd.connect_host = "socks";
717: fwd.listen_host = hpdelim(&arg);
718: if (fwd.listen_host == NULL ||
719: strlen(fwd.listen_host) >= NI_MAXHOST)
720: fatal("%.200s line %d: Bad forwarding specification.",
721: filename, linenum);
722: if (arg) {
723: fwd.listen_port = a2port(arg);
724: fwd.listen_host = cleanhostname(fwd.listen_host);
725: } else {
726: fwd.listen_port = a2port(fwd.listen_host);
1.143 djm 727: fwd.listen_host = NULL;
1.135 djm 728: }
729: if (fwd.listen_port == 0)
1.71 markus 730: fatal("%.200s line %d: Badly formatted port number.",
731: filename, linenum);
1.87 markus 732: if (*activep)
1.135 djm 733: add_local_forward(options, &fwd);
1.72 markus 734: break;
1.17 markus 735:
1.90 stevesk 736: case oClearAllForwardings:
737: intptr = &options->clear_forwardings;
738: goto parse_flag;
739:
1.17 markus 740: case oHost:
741: *activep = 0;
1.42 provos 742: while ((arg = strdelim(&s)) != NULL && *arg != '\0')
1.38 provos 743: if (match_pattern(host, arg)) {
744: debug("Applying options for %.100s", arg);
1.17 markus 745: *activep = 1;
746: break;
747: }
1.42 provos 748: /* Avoid garbage check below, as strdelim is done. */
1.17 markus 749: return 0;
750:
751: case oEscapeChar:
752: intptr = &options->escape_char;
1.42 provos 753: arg = strdelim(&s);
1.40 ho 754: if (!arg || *arg == '\0')
1.17 markus 755: fatal("%.200s line %d: Missing argument.", filename, linenum);
1.38 provos 756: if (arg[0] == '^' && arg[2] == 0 &&
1.51 markus 757: (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
758: value = (u_char) arg[1] & 31;
1.38 provos 759: else if (strlen(arg) == 1)
1.51 markus 760: value = (u_char) arg[0];
1.38 provos 761: else if (strcmp(arg, "none") == 0)
1.79 stevesk 762: value = SSH_ESCAPECHAR_NONE;
1.17 markus 763: else {
764: fatal("%.200s line %d: Bad escape character.",
1.93 deraadt 765: filename, linenum);
1.17 markus 766: /* NOTREACHED */
767: value = 0; /* Avoid compiler warning. */
768: }
769: if (*activep && *intptr == -1)
770: *intptr = value;
1.112 djm 771: break;
772:
773: case oAddressFamily:
774: arg = strdelim(&s);
1.140 markus 775: if (!arg || *arg == '\0')
776: fatal("%s line %d: missing address family.",
777: filename, linenum);
1.114 djm 778: intptr = &options->address_family;
1.112 djm 779: if (strcasecmp(arg, "inet") == 0)
1.114 djm 780: value = AF_INET;
1.112 djm 781: else if (strcasecmp(arg, "inet6") == 0)
1.114 djm 782: value = AF_INET6;
1.112 djm 783: else if (strcasecmp(arg, "any") == 0)
1.114 djm 784: value = AF_UNSPEC;
1.112 djm 785: else
786: fatal("Unsupported AddressFamily \"%s\"", arg);
1.114 djm 787: if (*activep && *intptr == -1)
788: *intptr = value;
1.17 markus 789: break;
790:
1.101 markus 791: case oEnableSSHKeysign:
792: intptr = &options->enable_ssh_keysign;
793: goto parse_flag;
794:
1.128 markus 795: case oIdentitiesOnly:
796: intptr = &options->identities_only;
797: goto parse_flag;
798:
1.127 markus 799: case oServerAliveInterval:
800: intptr = &options->server_alive_interval;
801: goto parse_time;
802:
803: case oServerAliveCountMax:
804: intptr = &options->server_alive_count_max;
805: goto parse_int;
806:
1.130 djm 807: case oSendEnv:
808: while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
809: if (strchr(arg, '=') != NULL)
810: fatal("%s line %d: Invalid environment name.",
811: filename, linenum);
1.137 djm 812: if (!*activep)
813: continue;
1.130 djm 814: if (options->num_send_env >= MAX_SEND_ENV)
815: fatal("%s line %d: too many send env.",
816: filename, linenum);
817: options->send_env[options->num_send_env++] =
818: xstrdup(arg);
819: }
820: break;
821:
1.132 djm 822: case oControlPath:
823: charptr = &options->control_path;
824: goto parse_string;
825:
826: case oControlMaster:
827: intptr = &options->control_master;
1.141 djm 828: arg = strdelim(&s);
829: if (!arg || *arg == '\0')
830: fatal("%.200s line %d: Missing ControlMaster argument.",
831: filename, linenum);
832: value = 0; /* To avoid compiler warning... */
833: if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
834: value = SSHCTL_MASTER_YES;
835: else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
836: value = SSHCTL_MASTER_NO;
837: else if (strcmp(arg, "auto") == 0)
838: value = SSHCTL_MASTER_AUTO;
839: else if (strcmp(arg, "ask") == 0)
840: value = SSHCTL_MASTER_ASK;
841: else if (strcmp(arg, "autoask") == 0)
842: value = SSHCTL_MASTER_AUTO_ASK;
843: else
844: fatal("%.200s line %d: Bad ControlMaster argument.",
845: filename, linenum);
846: if (*activep && *intptr == -1)
847: *intptr = value;
848: break;
1.132 djm 849:
1.136 djm 850: case oHashKnownHosts:
851: intptr = &options->hash_known_hosts;
852: goto parse_flag;
853:
1.144 reyk 854: case oTunnel:
855: intptr = &options->tun_open;
1.145 reyk 856: arg = strdelim(&s);
857: if (!arg || *arg == '\0')
858: fatal("%s line %d: Missing yes/point-to-point/"
859: "ethernet/no argument.", filename, linenum);
860: value = 0; /* silence compiler */
861: if (strcasecmp(arg, "ethernet") == 0)
862: value = SSH_TUNMODE_ETHERNET;
863: else if (strcasecmp(arg, "point-to-point") == 0)
864: value = SSH_TUNMODE_POINTOPOINT;
865: else if (strcasecmp(arg, "yes") == 0)
866: value = SSH_TUNMODE_DEFAULT;
867: else if (strcasecmp(arg, "no") == 0)
868: value = SSH_TUNMODE_NO;
869: else
870: fatal("%s line %d: Bad yes/point-to-point/ethernet/"
871: "no argument: %s", filename, linenum, arg);
872: if (*activep)
873: *intptr = value;
874: break;
1.144 reyk 875:
876: case oTunnelDevice:
877: arg = strdelim(&s);
878: if (!arg || *arg == '\0')
879: fatal("%.200s line %d: Missing argument.", filename, linenum);
880: value = a2tun(arg, &value2);
1.145 reyk 881: if (value == SSH_TUNID_ERR)
1.144 reyk 882: fatal("%.200s line %d: Bad tun device.", filename, linenum);
883: if (*activep) {
884: options->tun_local = value;
885: options->tun_remote = value2;
886: }
887: break;
888:
889: case oLocalCommand:
890: charptr = &options->local_command;
891: goto parse_command;
892:
893: case oPermitLocalCommand:
894: intptr = &options->permit_local_command;
895: goto parse_flag;
896:
1.96 markus 897: case oDeprecated:
1.98 markus 898: debug("%s line %d: Deprecated option \"%s\"",
1.96 markus 899: filename, linenum, keyword);
1.98 markus 900: return 0;
1.96 markus 901:
1.110 jakob 902: case oUnsupported:
903: error("%s line %d: Unsupported option \"%s\"",
904: filename, linenum, keyword);
905: return 0;
906:
1.17 markus 907: default:
908: fatal("process_config_line: Unimplemented opcode %d", opcode);
909: }
910:
911: /* Check that there is no garbage at end of line. */
1.57 djm 912: if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1.39 ho 913: fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1.142 djm 914: filename, linenum, arg);
1.39 ho 915: }
1.17 markus 916: return 0;
1.1 deraadt 917: }
918:
919:
1.19 markus 920: /*
921: * Reads the config file and modifies the options accordingly. Options
922: * should already be initialized before this call. This never returns if
1.89 stevesk 923: * there is an error. If the file does not exist, this returns 0.
1.19 markus 924: */
1.1 deraadt 925:
1.89 stevesk 926: int
1.134 deraadt 927: read_config_file(const char *filename, const char *host, Options *options,
1.129 djm 928: int checkperm)
1.1 deraadt 929: {
1.17 markus 930: FILE *f;
931: char line[1024];
932: int active, linenum;
933: int bad_options = 0;
934:
935: /* Open the file. */
1.129 djm 936: if ((f = fopen(filename, "r")) == NULL)
1.89 stevesk 937: return 0;
1.129 djm 938:
939: if (checkperm) {
940: struct stat sb;
1.134 deraadt 941:
1.131 dtucker 942: if (fstat(fileno(f), &sb) == -1)
1.129 djm 943: fatal("fstat %s: %s", filename, strerror(errno));
944: if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1.131 dtucker 945: (sb.st_mode & 022) != 0))
1.129 djm 946: fatal("Bad owner or permissions on %s", filename);
947: }
1.17 markus 948:
949: debug("Reading configuration data %.200s", filename);
950:
1.19 markus 951: /*
952: * Mark that we are now processing the options. This flag is turned
953: * on/off by Host specifications.
954: */
1.17 markus 955: active = 1;
956: linenum = 0;
957: while (fgets(line, sizeof(line), f)) {
958: /* Update line number counter. */
959: linenum++;
960: if (process_config_line(options, host, line, filename, linenum, &active) != 0)
961: bad_options++;
962: }
963: fclose(f);
964: if (bad_options > 0)
1.64 millert 965: fatal("%s: terminating, %d bad configuration options",
1.93 deraadt 966: filename, bad_options);
1.89 stevesk 967: return 1;
1.1 deraadt 968: }
969:
1.19 markus 970: /*
971: * Initializes options to special values that indicate that they have not yet
972: * been set. Read_config_file will only set options with this value. Options
973: * are processed in the following order: command line, user config file,
974: * system config file. Last, fill_default_options is called.
975: */
1.1 deraadt 976:
1.26 markus 977: void
1.17 markus 978: initialize_options(Options * options)
1.1 deraadt 979: {
1.17 markus 980: memset(options, 'X', sizeof(*options));
981: options->forward_agent = -1;
982: options->forward_x11 = -1;
1.123 markus 983: options->forward_x11_trusted = -1;
1.34 markus 984: options->xauth_location = NULL;
1.17 markus 985: options->gateway_ports = -1;
986: options->use_privileged_port = -1;
987: options->rsa_authentication = -1;
1.50 markus 988: options->pubkey_authentication = -1;
1.78 markus 989: options->challenge_response_authentication = -1;
1.118 markus 990: options->gss_authentication = -1;
991: options->gss_deleg_creds = -1;
1.17 markus 992: options->password_authentication = -1;
1.48 markus 993: options->kbd_interactive_authentication = -1;
994: options->kbd_interactive_devices = NULL;
1.17 markus 995: options->rhosts_rsa_authentication = -1;
1.72 markus 996: options->hostbased_authentication = -1;
1.17 markus 997: options->batch_mode = -1;
998: options->check_host_ip = -1;
999: options->strict_host_key_checking = -1;
1000: options->compression = -1;
1.126 markus 1001: options->tcp_keep_alive = -1;
1.17 markus 1002: options->compression_level = -1;
1003: options->port = -1;
1.114 djm 1004: options->address_family = -1;
1.17 markus 1005: options->connection_attempts = -1;
1.111 djm 1006: options->connection_timeout = -1;
1.17 markus 1007: options->number_of_password_prompts = -1;
1008: options->cipher = -1;
1.25 markus 1009: options->ciphers = NULL;
1.62 markus 1010: options->macs = NULL;
1.76 markus 1011: options->hostkeyalgorithms = NULL;
1.25 markus 1012: options->protocol = SSH_PROTO_UNKNOWN;
1.17 markus 1013: options->num_identity_files = 0;
1014: options->hostname = NULL;
1.52 markus 1015: options->host_key_alias = NULL;
1.17 markus 1016: options->proxy_command = NULL;
1017: options->user = NULL;
1018: options->escape_char = -1;
1019: options->system_hostfile = NULL;
1020: options->user_hostfile = NULL;
1.27 markus 1021: options->system_hostfile2 = NULL;
1022: options->user_hostfile2 = NULL;
1.17 markus 1023: options->num_local_forwards = 0;
1024: options->num_remote_forwards = 0;
1.90 stevesk 1025: options->clear_forwardings = -1;
1.95 markus 1026: options->log_level = SYSLOG_LEVEL_NOT_SET;
1.67 markus 1027: options->preferred_authentications = NULL;
1.77 markus 1028: options->bind_address = NULL;
1.86 markus 1029: options->smartcard_device = NULL;
1.101 markus 1030: options->enable_ssh_keysign = - 1;
1.91 markus 1031: options->no_host_authentication_for_localhost = - 1;
1.128 markus 1032: options->identities_only = - 1;
1.105 markus 1033: options->rekey_limit = - 1;
1.107 jakob 1034: options->verify_host_key_dns = -1;
1.127 markus 1035: options->server_alive_interval = -1;
1036: options->server_alive_count_max = -1;
1.130 djm 1037: options->num_send_env = 0;
1.132 djm 1038: options->control_path = NULL;
1039: options->control_master = -1;
1.136 djm 1040: options->hash_known_hosts = -1;
1.144 reyk 1041: options->tun_open = -1;
1042: options->tun_local = -1;
1043: options->tun_remote = -1;
1044: options->local_command = NULL;
1045: options->permit_local_command = -1;
1.1 deraadt 1046: }
1047:
1.19 markus 1048: /*
1049: * Called after processing other sources of option data, this fills those
1050: * options for which no value has been specified with their default values.
1051: */
1.1 deraadt 1052:
1.26 markus 1053: void
1.17 markus 1054: fill_default_options(Options * options)
1.1 deraadt 1055: {
1.61 deraadt 1056: int len;
1057:
1.17 markus 1058: if (options->forward_agent == -1)
1.33 markus 1059: options->forward_agent = 0;
1.17 markus 1060: if (options->forward_x11 == -1)
1.23 markus 1061: options->forward_x11 = 0;
1.123 markus 1062: if (options->forward_x11_trusted == -1)
1063: options->forward_x11_trusted = 0;
1.34 markus 1064: if (options->xauth_location == NULL)
1.80 markus 1065: options->xauth_location = _PATH_XAUTH;
1.17 markus 1066: if (options->gateway_ports == -1)
1067: options->gateway_ports = 0;
1068: if (options->use_privileged_port == -1)
1.65 markus 1069: options->use_privileged_port = 0;
1.17 markus 1070: if (options->rsa_authentication == -1)
1071: options->rsa_authentication = 1;
1.50 markus 1072: if (options->pubkey_authentication == -1)
1073: options->pubkey_authentication = 1;
1.78 markus 1074: if (options->challenge_response_authentication == -1)
1.83 markus 1075: options->challenge_response_authentication = 1;
1.118 markus 1076: if (options->gss_authentication == -1)
1.122 markus 1077: options->gss_authentication = 0;
1.118 markus 1078: if (options->gss_deleg_creds == -1)
1079: options->gss_deleg_creds = 0;
1.17 markus 1080: if (options->password_authentication == -1)
1081: options->password_authentication = 1;
1.48 markus 1082: if (options->kbd_interactive_authentication == -1)
1.59 markus 1083: options->kbd_interactive_authentication = 1;
1.17 markus 1084: if (options->rhosts_rsa_authentication == -1)
1.99 stevesk 1085: options->rhosts_rsa_authentication = 0;
1.72 markus 1086: if (options->hostbased_authentication == -1)
1087: options->hostbased_authentication = 0;
1.17 markus 1088: if (options->batch_mode == -1)
1089: options->batch_mode = 0;
1090: if (options->check_host_ip == -1)
1091: options->check_host_ip = 1;
1092: if (options->strict_host_key_checking == -1)
1093: options->strict_host_key_checking = 2; /* 2 is default */
1094: if (options->compression == -1)
1095: options->compression = 0;
1.126 markus 1096: if (options->tcp_keep_alive == -1)
1097: options->tcp_keep_alive = 1;
1.17 markus 1098: if (options->compression_level == -1)
1099: options->compression_level = 6;
1100: if (options->port == -1)
1101: options->port = 0; /* Filled in ssh_connect. */
1.114 djm 1102: if (options->address_family == -1)
1103: options->address_family = AF_UNSPEC;
1.17 markus 1104: if (options->connection_attempts == -1)
1.84 markus 1105: options->connection_attempts = 1;
1.17 markus 1106: if (options->number_of_password_prompts == -1)
1107: options->number_of_password_prompts = 3;
1108: /* Selected in ssh_login(). */
1109: if (options->cipher == -1)
1110: options->cipher = SSH_CIPHER_NOT_SET;
1.31 markus 1111: /* options->ciphers, default set in myproposals.h */
1.62 markus 1112: /* options->macs, default set in myproposals.h */
1.76 markus 1113: /* options->hostkeyalgorithms, default set in myproposals.h */
1.25 markus 1114: if (options->protocol == SSH_PROTO_UNKNOWN)
1.69 markus 1115: options->protocol = SSH_PROTO_1|SSH_PROTO_2;
1.17 markus 1116: if (options->num_identity_files == 0) {
1.50 markus 1117: if (options->protocol & SSH_PROTO_1) {
1.61 deraadt 1118: len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1.50 markus 1119: options->identity_files[options->num_identity_files] =
1.61 deraadt 1120: xmalloc(len);
1121: snprintf(options->identity_files[options->num_identity_files++],
1122: len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1.50 markus 1123: }
1124: if (options->protocol & SSH_PROTO_2) {
1.63 deraadt 1125: len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1126: options->identity_files[options->num_identity_files] =
1127: xmalloc(len);
1128: snprintf(options->identity_files[options->num_identity_files++],
1129: len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1130:
1.61 deraadt 1131: len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1.50 markus 1132: options->identity_files[options->num_identity_files] =
1.61 deraadt 1133: xmalloc(len);
1134: snprintf(options->identity_files[options->num_identity_files++],
1135: len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1.50 markus 1136: }
1.27 markus 1137: }
1.17 markus 1138: if (options->escape_char == -1)
1139: options->escape_char = '~';
1140: if (options->system_hostfile == NULL)
1.55 markus 1141: options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1.17 markus 1142: if (options->user_hostfile == NULL)
1.55 markus 1143: options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1.27 markus 1144: if (options->system_hostfile2 == NULL)
1.55 markus 1145: options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1.27 markus 1146: if (options->user_hostfile2 == NULL)
1.55 markus 1147: options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1.95 markus 1148: if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1.54 markus 1149: options->log_level = SYSLOG_LEVEL_INFO;
1.90 stevesk 1150: if (options->clear_forwardings == 1)
1151: clear_forwardings(options);
1.91 markus 1152: if (options->no_host_authentication_for_localhost == - 1)
1153: options->no_host_authentication_for_localhost = 0;
1.128 markus 1154: if (options->identities_only == -1)
1155: options->identities_only = 0;
1.101 markus 1156: if (options->enable_ssh_keysign == -1)
1157: options->enable_ssh_keysign = 0;
1.105 markus 1158: if (options->rekey_limit == -1)
1159: options->rekey_limit = 0;
1.107 jakob 1160: if (options->verify_host_key_dns == -1)
1161: options->verify_host_key_dns = 0;
1.127 markus 1162: if (options->server_alive_interval == -1)
1163: options->server_alive_interval = 0;
1164: if (options->server_alive_count_max == -1)
1165: options->server_alive_count_max = 3;
1.132 djm 1166: if (options->control_master == -1)
1167: options->control_master = 0;
1.136 djm 1168: if (options->hash_known_hosts == -1)
1169: options->hash_known_hosts = 0;
1.144 reyk 1170: if (options->tun_open == -1)
1.145 reyk 1171: options->tun_open = SSH_TUNMODE_NO;
1172: if (options->tun_local == -1)
1173: options->tun_local = SSH_TUNID_ANY;
1174: if (options->tun_remote == -1)
1175: options->tun_remote = SSH_TUNID_ANY;
1.144 reyk 1176: if (options->permit_local_command == -1)
1177: options->permit_local_command = 0;
1178: /* options->local_command should not be set by default */
1.17 markus 1179: /* options->proxy_command should not be set by default */
1180: /* options->user will be set in the main program if appropriate */
1181: /* options->hostname will be set in the main program if appropriate */
1.52 markus 1182: /* options->host_key_alias should not be set by default */
1.67 markus 1183: /* options->preferred_authentications will be set in ssh */
1.135 djm 1184: }
1185:
1186: /*
1187: * parse_forward
1188: * parses a string containing a port forwarding specification of the form:
1189: * [listenhost:]listenport:connecthost:connectport
1190: * returns number of arguments parsed or zero on error
1191: */
1192: int
1193: parse_forward(Forward *fwd, const char *fwdspec)
1194: {
1195: int i;
1196: char *p, *cp, *fwdarg[4];
1197:
1198: memset(fwd, '\0', sizeof(*fwd));
1199:
1200: cp = p = xstrdup(fwdspec);
1201:
1202: /* skip leading spaces */
1203: while (*cp && isspace(*cp))
1204: cp++;
1205:
1206: for (i = 0; i < 4; ++i)
1207: if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1208: break;
1209:
1210: /* Check for trailing garbage in 4-arg case*/
1211: if (cp != NULL)
1212: i = 0; /* failure */
1213:
1214: switch (i) {
1215: case 3:
1216: fwd->listen_host = NULL;
1217: fwd->listen_port = a2port(fwdarg[0]);
1218: fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1219: fwd->connect_port = a2port(fwdarg[2]);
1220: break;
1221:
1222: case 4:
1223: fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1224: fwd->listen_port = a2port(fwdarg[1]);
1225: fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1226: fwd->connect_port = a2port(fwdarg[3]);
1227: break;
1228: default:
1229: i = 0; /* failure */
1230: }
1231:
1232: xfree(p);
1233:
1234: if (fwd->listen_port == 0 && fwd->connect_port == 0)
1235: goto fail_free;
1236:
1237: if (fwd->connect_host != NULL &&
1238: strlen(fwd->connect_host) >= NI_MAXHOST)
1239: goto fail_free;
1240:
1241: return (i);
1242:
1243: fail_free:
1244: if (fwd->connect_host != NULL)
1245: xfree(fwd->connect_host);
1246: if (fwd->listen_host != NULL)
1247: xfree(fwd->listen_host);
1248: return (0);
1.1 deraadt 1249: }