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