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