]> andersk Git - gssapi-openssh.git/blame - openssh/readconf.c
Initial revision
[gssapi-openssh.git] / openssh / readconf.c
CommitLineData
3c0ef626 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#include "includes.h"
7cac2b65 15RCSID("$OpenBSD: readconf.c,v 1.121 2003/09/01 18:15:50 markus Exp $");
3c0ef626 16
17#include "ssh.h"
18#include "xmalloc.h"
19#include "compat.h"
20#include "cipher.h"
21#include "pathnames.h"
22#include "log.h"
23#include "readconf.h"
24#include "match.h"
25#include "misc.h"
26#include "kex.h"
27#include "mac.h"
28
29/* Format of the configuration file:
30
31 # Configuration data is parsed as follows:
32 # 1. command line options
33 # 2. user-specific file
34 # 3. system-wide file
35 # Any configuration value is only changed the first time it is set.
36 # Thus, host-specific definitions should be at the beginning of the
37 # configuration file, and defaults at the end.
38
39 # Host-specific declarations. These may override anything above. A single
40 # host may match multiple declarations; these are processed in the order
41 # that they are given in.
42
43 Host *.ngs.fi ngs.fi
44a053a3 44 User foo
3c0ef626 45
46 Host fake.com
47 HostName another.host.name.real.org
48 User blaah
49 Port 34289
50 ForwardX11 no
51 ForwardAgent no
52
53 Host books.com
54 RemoteForward 9999 shadows.cs.hut.fi:9999
55 Cipher 3des
56
57 Host fascist.blob.com
58 Port 23123
59 User tylonen
3c0ef626 60 PasswordAuthentication no
61
62 Host puukko.hut.fi
63 User t35124p
64 ProxyCommand ssh-proxy %h %p
65
66 Host *.fr
44a053a3 67 PublicKeyAuthentication no
3c0ef626 68
69 Host *.su
70 Cipher none
71 PasswordAuthentication no
72
73 # Defaults for various options
74 Host *
75 ForwardAgent no
76 ForwardX11 no
3c0ef626 77 PasswordAuthentication yes
78 RSAAuthentication yes
79 RhostsRSAAuthentication yes
3c0ef626 80 StrictHostKeyChecking yes
81 KeepAlives no
82 IdentityFile ~/.ssh/identity
83 Port 22
84 EscapeChar ~
85
86*/
87
88/* Keyword tokens. */
89
90typedef enum {
91 oBadOption,
7cac2b65 92 oForwardAgent, oForwardX11, oGatewayPorts,
44a053a3 93 oPasswordAuthentication, oRSAAuthentication,
3c0ef626 94 oChallengeResponseAuthentication, oXAuthLocation,
3c0ef626 95 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
96 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
97 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
98 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
99 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
100 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
101 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
102 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
103 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
104 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
44a053a3 105 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
7cac2b65 106 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
107 oAddressFamily, oGssAuthentication, oGssKeyEx, oGssDelegateCreds,
108 oDeprecated, oUnsupported
3c0ef626 109} OpCodes;
110
111/* Textual representations of the tokens. */
112
113static struct {
114 const char *name;
115 OpCodes opcode;
116} keywords[] = {
117 { "forwardagent", oForwardAgent },
118 { "forwardx11", oForwardX11 },
119 { "xauthlocation", oXAuthLocation },
120 { "gatewayports", oGatewayPorts },
121 { "useprivilegedport", oUsePrivilegedPort },
7cac2b65 122 { "rhostsauthentication", oDeprecated },
3c0ef626 123 { "passwordauthentication", oPasswordAuthentication },
124 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
125 { "kbdinteractivedevices", oKbdInteractiveDevices },
126 { "rsaauthentication", oRSAAuthentication },
127 { "pubkeyauthentication", oPubkeyAuthentication },
128 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
129 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
130 { "hostbasedauthentication", oHostbasedAuthentication },
131 { "challengeresponseauthentication", oChallengeResponseAuthentication },
132 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
133 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
7cac2b65 134 { "kerberosauthentication", oUnsupported },
135 { "kerberostgtpassing", oUnsupported },
136 { "afstokenpassing", oUnsupported },
137#if defined(GSSAPI)
5598e598 138 { "gssapiauthentication", oGssAuthentication },
7a056ed1 139 { "gssapikeyexchange", oGssKeyEx },
5598e598 140 { "gssapidelegatecredentials", oGssDelegateCreds },
7cac2b65 141#else
142 { "gssapiauthentication", oUnsupported },
143 { "gssapikeyexchange", oUnsupported },
144 { "gssapidelegatecredentials", oUnsupported },
3c0ef626 145#endif
44a053a3 146 { "fallbacktorsh", oDeprecated },
147 { "usersh", oDeprecated },
3c0ef626 148 { "identityfile", oIdentityFile },
149 { "identityfile2", oIdentityFile }, /* alias */
150 { "hostname", oHostName },
151 { "hostkeyalias", oHostKeyAlias },
152 { "proxycommand", oProxyCommand },
153 { "port", oPort },
154 { "cipher", oCipher },
155 { "ciphers", oCiphers },
156 { "macs", oMacs },
157 { "protocol", oProtocol },
158 { "remoteforward", oRemoteForward },
159 { "localforward", oLocalForward },
160 { "user", oUser },
161 { "host", oHost },
162 { "escapechar", oEscapeChar },
163 { "globalknownhostsfile", oGlobalKnownHostsFile },
164 { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */
165 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
166 { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */
167 { "connectionattempts", oConnectionAttempts },
168 { "batchmode", oBatchMode },
169 { "checkhostip", oCheckHostIP },
170 { "stricthostkeychecking", oStrictHostKeyChecking },
171 { "compression", oCompression },
172 { "compressionlevel", oCompressionLevel },
173 { "keepalive", oKeepAlives },
174 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
175 { "loglevel", oLogLevel },
176 { "dynamicforward", oDynamicForward },
177 { "preferredauthentications", oPreferredAuthentications },
178 { "hostkeyalgorithms", oHostKeyAlgorithms },
179 { "bindaddress", oBindAddress },
7cac2b65 180#ifdef SMARTCARD
3c0ef626 181 { "smartcarddevice", oSmartcardDevice },
7cac2b65 182#else
183 { "smartcarddevice", oUnsupported },
184#endif
e9702f7d 185 { "clearallforwardings", oClearAllForwardings },
bfe49944 186 { "enablesshkeysign", oEnableSSHKeysign },
7cac2b65 187#ifdef DNS
188 { "verifyhostkeydns", oVerifyHostKeyDNS },
189#else
190 { "verifyhostkeydns", oUnsupported },
191#endif
e9702f7d 192 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
7cac2b65 193 { "rekeylimit", oRekeyLimit },
194 { "connecttimeout", oConnectTimeout },
195 { "addressfamily", oAddressFamily },
e9702f7d 196 { NULL, oBadOption }
3c0ef626 197};
198
199/*
200 * Adds a local TCP/IP port forward to options. Never returns if there is an
201 * error.
202 */
203
204void
205add_local_forward(Options *options, u_short port, const char *host,
206 u_short host_port)
207{
208 Forward *fwd;
d03f4262 209#ifndef NO_IPPORT_RESERVED_CONCEPT
3c0ef626 210 extern uid_t original_real_uid;
211 if (port < IPPORT_RESERVED && original_real_uid != 0)
212 fatal("Privileged ports can only be forwarded by root.");
213#endif
214 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
215 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
216 fwd = &options->local_forwards[options->num_local_forwards++];
217 fwd->port = port;
218 fwd->host = xstrdup(host);
219 fwd->host_port = host_port;
220}
221
222/*
223 * Adds a remote TCP/IP port forward to options. Never returns if there is
224 * an error.
225 */
226
227void
228add_remote_forward(Options *options, u_short port, const char *host,
229 u_short host_port)
230{
231 Forward *fwd;
232 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
233 fatal("Too many remote forwards (max %d).",
e9702f7d 234 SSH_MAX_FORWARDS_PER_DIRECTION);
3c0ef626 235 fwd = &options->remote_forwards[options->num_remote_forwards++];
236 fwd->port = port;
237 fwd->host = xstrdup(host);
238 fwd->host_port = host_port;
239}
240
241static void
242clear_forwardings(Options *options)
243{
244 int i;
245
246 for (i = 0; i < options->num_local_forwards; i++)
247 xfree(options->local_forwards[i].host);
248 options->num_local_forwards = 0;
249 for (i = 0; i < options->num_remote_forwards; i++)
250 xfree(options->remote_forwards[i].host);
251 options->num_remote_forwards = 0;
252}
253
254/*
255 * Returns the number of the token pointed to by cp or oBadOption.
256 */
257
258static OpCodes
259parse_token(const char *cp, const char *filename, int linenum)
260{
261 u_int i;
262
263 for (i = 0; keywords[i].name; i++)
264 if (strcasecmp(cp, keywords[i].name) == 0)
265 return keywords[i].opcode;
266
267 error("%s: line %d: Bad configuration option: %s",
268 filename, linenum, cp);
269 return oBadOption;
270}
271
272/*
273 * Processes a single option line as used in the configuration files. This
274 * only sets those values that have not already been set.
275 */
bfe49944 276#define WHITESPACE " \t\r\n"
3c0ef626 277
278int
279process_config_line(Options *options, const char *host,
280 char *line, const char *filename, int linenum,
281 int *activep)
282{
bfe49944 283 char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
3c0ef626 284 int opcode, *intptr, value;
bfe49944 285 size_t len;
3c0ef626 286 u_short fwd_port, fwd_host_port;
287 char sfwd_host_port[6];
288
7cac2b65 289 /* Strip trailing whitespace */
290 for(len = strlen(line) - 1; len > 0; len--) {
291 if (strchr(WHITESPACE, line[len]) == NULL)
292 break;
293 line[len] = '\0';
294 }
295
3c0ef626 296 s = line;
297 /* Get the keyword. (Each line is supposed to begin with a keyword). */
298 keyword = strdelim(&s);
299 /* Ignore leading whitespace. */
300 if (*keyword == '\0')
301 keyword = strdelim(&s);
302 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
303 return 0;
304
305 opcode = parse_token(keyword, filename, linenum);
306
307 switch (opcode) {
308 case oBadOption:
309 /* don't panic, but count bad options */
310 return -1;
311 /* NOTREACHED */
7cac2b65 312 case oConnectTimeout:
313 intptr = &options->connection_timeout;
314/* parse_time: */
315 arg = strdelim(&s);
316 if (!arg || *arg == '\0')
317 fatal("%s line %d: missing time value.",
318 filename, linenum);
319 if ((value = convtime(arg)) == -1)
320 fatal("%s line %d: invalid time value.",
321 filename, linenum);
322 if (*intptr == -1)
323 *intptr = value;
324 break;
325
3c0ef626 326 case oForwardAgent:
327 intptr = &options->forward_agent;
328parse_flag:
329 arg = strdelim(&s);
330 if (!arg || *arg == '\0')
331 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
332 value = 0; /* To avoid compiler warning... */
333 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
334 value = 1;
335 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
336 value = 0;
337 else
338 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
339 if (*activep && *intptr == -1)
340 *intptr = value;
341 break;
342
343 case oForwardX11:
344 intptr = &options->forward_x11;
345 goto parse_flag;
346
347 case oGatewayPorts:
348 intptr = &options->gateway_ports;
349 goto parse_flag;
350
351 case oUsePrivilegedPort:
352 intptr = &options->use_privileged_port;
353 goto parse_flag;
354
3c0ef626 355 case oPasswordAuthentication:
356 intptr = &options->password_authentication;
357 goto parse_flag;
358
359 case oKbdInteractiveAuthentication:
360 intptr = &options->kbd_interactive_authentication;
361 goto parse_flag;
362
363 case oKbdInteractiveDevices:
364 charptr = &options->kbd_interactive_devices;
365 goto parse_string;
366
367 case oPubkeyAuthentication:
368 intptr = &options->pubkey_authentication;
369 goto parse_flag;
370
371 case oRSAAuthentication:
372 intptr = &options->rsa_authentication;
373 goto parse_flag;
374
375 case oRhostsRSAAuthentication:
376 intptr = &options->rhosts_rsa_authentication;
377 goto parse_flag;
378
379 case oHostbasedAuthentication:
380 intptr = &options->hostbased_authentication;
381 goto parse_flag;
382
383 case oChallengeResponseAuthentication:
384 intptr = &options->challenge_response_authentication;
385 goto parse_flag;
7cac2b65 386
5598e598 387 case oGssAuthentication:
388 intptr = &options->gss_authentication;
389 goto parse_flag;
7cac2b65 390
7a056ed1 391 case oGssKeyEx:
392 intptr = &options->gss_keyex;
393 goto parse_flag;
394
5598e598 395 case oGssDelegateCreds:
396 intptr = &options->gss_deleg_creds;
397 goto parse_flag;
5598e598 398
3c0ef626 399 case oBatchMode:
400 intptr = &options->batch_mode;
401 goto parse_flag;
402
403 case oCheckHostIP:
404 intptr = &options->check_host_ip;
405 goto parse_flag;
406
7cac2b65 407 case oVerifyHostKeyDNS:
408 intptr = &options->verify_host_key_dns;
409 goto parse_flag;
410
3c0ef626 411 case oStrictHostKeyChecking:
412 intptr = &options->strict_host_key_checking;
413 arg = strdelim(&s);
414 if (!arg || *arg == '\0')
415 fatal("%.200s line %d: Missing yes/no/ask argument.",
e9702f7d 416 filename, linenum);
3c0ef626 417 value = 0; /* To avoid compiler warning... */
418 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
419 value = 1;
420 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
421 value = 0;
422 else if (strcmp(arg, "ask") == 0)
423 value = 2;
424 else
425 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
426 if (*activep && *intptr == -1)
427 *intptr = value;
428 break;
429
430 case oCompression:
431 intptr = &options->compression;
432 goto parse_flag;
433
434 case oKeepAlives:
435 intptr = &options->keepalives;
436 goto parse_flag;
437
438 case oNoHostAuthenticationForLocalhost:
439 intptr = &options->no_host_authentication_for_localhost;
440 goto parse_flag;
441
442 case oNumberOfPasswordPrompts:
443 intptr = &options->number_of_password_prompts;
444 goto parse_int;
445
446 case oCompressionLevel:
447 intptr = &options->compression_level;
448 goto parse_int;
449
7cac2b65 450 case oRekeyLimit:
451 intptr = &options->rekey_limit;
452 arg = strdelim(&s);
453 if (!arg || *arg == '\0')
454 fatal("%.200s line %d: Missing argument.", filename, linenum);
455 if (arg[0] < '0' || arg[0] > '9')
456 fatal("%.200s line %d: Bad number.", filename, linenum);
457 value = strtol(arg, &endofnumber, 10);
458 if (arg == endofnumber)
459 fatal("%.200s line %d: Bad number.", filename, linenum);
460 switch (toupper(*endofnumber)) {
461 case 'K':
462 value *= 1<<10;
463 break;
464 case 'M':
465 value *= 1<<20;
466 break;
467 case 'G':
468 value *= 1<<30;
469 break;
470 }
471 if (*activep && *intptr == -1)
472 *intptr = value;
473 break;
474
3c0ef626 475 case oIdentityFile:
476 arg = strdelim(&s);
477 if (!arg || *arg == '\0')
478 fatal("%.200s line %d: Missing argument.", filename, linenum);
479 if (*activep) {
480 intptr = &options->num_identity_files;
481 if (*intptr >= SSH_MAX_IDENTITY_FILES)
482 fatal("%.200s line %d: Too many identity files specified (max %d).",
e9702f7d 483 filename, linenum, SSH_MAX_IDENTITY_FILES);
3c0ef626 484 charptr = &options->identity_files[*intptr];
485 *charptr = xstrdup(arg);
486 *intptr = *intptr + 1;
487 }
488 break;
489
490 case oXAuthLocation:
491 charptr=&options->xauth_location;
492 goto parse_string;
493
494 case oUser:
495 charptr = &options->user;
496parse_string:
497 arg = strdelim(&s);
498 if (!arg || *arg == '\0')
499 fatal("%.200s line %d: Missing argument.", filename, linenum);
500 if (*activep && *charptr == NULL)
501 *charptr = xstrdup(arg);
502 break;
503
504 case oGlobalKnownHostsFile:
505 charptr = &options->system_hostfile;
506 goto parse_string;
507
508 case oUserKnownHostsFile:
509 charptr = &options->user_hostfile;
510 goto parse_string;
511
512 case oGlobalKnownHostsFile2:
513 charptr = &options->system_hostfile2;
514 goto parse_string;
515
516 case oUserKnownHostsFile2:
517 charptr = &options->user_hostfile2;
518 goto parse_string;
519
520 case oHostName:
521 charptr = &options->hostname;
522 goto parse_string;
523
524 case oHostKeyAlias:
525 charptr = &options->host_key_alias;
526 goto parse_string;
527
528 case oPreferredAuthentications:
529 charptr = &options->preferred_authentications;
530 goto parse_string;
531
532 case oBindAddress:
533 charptr = &options->bind_address;
534 goto parse_string;
535
536 case oSmartcardDevice:
537 charptr = &options->smartcard_device;
538 goto parse_string;
539
540 case oProxyCommand:
7cac2b65 541 if (s == NULL)
542 fatal("%.200s line %d: Missing argument.", filename, linenum);
3c0ef626 543 charptr = &options->proxy_command;
bfe49944 544 len = strspn(s, WHITESPACE "=");
3c0ef626 545 if (*activep && *charptr == NULL)
bfe49944 546 *charptr = xstrdup(s + len);
3c0ef626 547 return 0;
548
549 case oPort:
550 intptr = &options->port;
551parse_int:
552 arg = strdelim(&s);
553 if (!arg || *arg == '\0')
554 fatal("%.200s line %d: Missing argument.", filename, linenum);
555 if (arg[0] < '0' || arg[0] > '9')
556 fatal("%.200s line %d: Bad number.", filename, linenum);
557
558 /* Octal, decimal, or hex format? */
559 value = strtol(arg, &endofnumber, 0);
560 if (arg == endofnumber)
561 fatal("%.200s line %d: Bad number.", filename, linenum);
562 if (*activep && *intptr == -1)
563 *intptr = value;
564 break;
565
566 case oConnectionAttempts:
567 intptr = &options->connection_attempts;
568 goto parse_int;
569
570 case oCipher:
571 intptr = &options->cipher;
572 arg = strdelim(&s);
573 if (!arg || *arg == '\0')
574 fatal("%.200s line %d: Missing argument.", filename, linenum);
575 value = cipher_number(arg);
576 if (value == -1)
577 fatal("%.200s line %d: Bad cipher '%s'.",
e9702f7d 578 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 579 if (*activep && *intptr == -1)
580 *intptr = value;
581 break;
582
583 case oCiphers:
584 arg = strdelim(&s);
585 if (!arg || *arg == '\0')
586 fatal("%.200s line %d: Missing argument.", filename, linenum);
587 if (!ciphers_valid(arg))
588 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
e9702f7d 589 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 590 if (*activep && options->ciphers == NULL)
591 options->ciphers = xstrdup(arg);
592 break;
593
594 case oMacs:
595 arg = strdelim(&s);
596 if (!arg || *arg == '\0')
597 fatal("%.200s line %d: Missing argument.", filename, linenum);
598 if (!mac_valid(arg))
599 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
e9702f7d 600 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 601 if (*activep && options->macs == NULL)
602 options->macs = xstrdup(arg);
603 break;
604
605 case oHostKeyAlgorithms:
606 arg = strdelim(&s);
607 if (!arg || *arg == '\0')
608 fatal("%.200s line %d: Missing argument.", filename, linenum);
609 if (!key_names_valid2(arg))
610 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
e9702f7d 611 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 612 if (*activep && options->hostkeyalgorithms == NULL)
613 options->hostkeyalgorithms = xstrdup(arg);
614 break;
615
616 case oProtocol:
617 intptr = &options->protocol;
618 arg = strdelim(&s);
619 if (!arg || *arg == '\0')
620 fatal("%.200s line %d: Missing argument.", filename, linenum);
621 value = proto_spec(arg);
622 if (value == SSH_PROTO_UNKNOWN)
623 fatal("%.200s line %d: Bad protocol spec '%s'.",
e9702f7d 624 filename, linenum, arg ? arg : "<NONE>");
3c0ef626 625 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
626 *intptr = value;
627 break;
628
629 case oLogLevel:
630 intptr = (int *) &options->log_level;
631 arg = strdelim(&s);
632 value = log_level_number(arg);
e9702f7d 633 if (value == SYSLOG_LEVEL_NOT_SET)
3c0ef626 634 fatal("%.200s line %d: unsupported log level '%s'",
e9702f7d 635 filename, linenum, arg ? arg : "<NONE>");
636 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
3c0ef626 637 *intptr = (LogLevel) value;
638 break;
639
640 case oLocalForward:
641 case oRemoteForward:
642 arg = strdelim(&s);
643 if (!arg || *arg == '\0')
644 fatal("%.200s line %d: Missing port argument.",
645 filename, linenum);
646 if ((fwd_port = a2port(arg)) == 0)
647 fatal("%.200s line %d: Bad listen port.",
648 filename, linenum);
649 arg = strdelim(&s);
650 if (!arg || *arg == '\0')
651 fatal("%.200s line %d: Missing second argument.",
652 filename, linenum);
653 if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
654 sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
655 fatal("%.200s line %d: Bad forwarding specification.",
656 filename, linenum);
657 if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
658 fatal("%.200s line %d: Bad forwarding port.",
659 filename, linenum);
660 if (*activep) {
661 if (opcode == oLocalForward)
662 add_local_forward(options, fwd_port, buf,
663 fwd_host_port);
664 else if (opcode == oRemoteForward)
665 add_remote_forward(options, fwd_port, buf,
666 fwd_host_port);
667 }
668 break;
669
670 case oDynamicForward:
671 arg = strdelim(&s);
672 if (!arg || *arg == '\0')
673 fatal("%.200s line %d: Missing port argument.",
674 filename, linenum);
675 fwd_port = a2port(arg);
676 if (fwd_port == 0)
677 fatal("%.200s line %d: Badly formatted port number.",
678 filename, linenum);
679 if (*activep)
7cac2b65 680 add_local_forward(options, fwd_port, "socks", 0);
3c0ef626 681 break;
682
683 case oClearAllForwardings:
684 intptr = &options->clear_forwardings;
685 goto parse_flag;
686
687 case oHost:
688 *activep = 0;
689 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
690 if (match_pattern(host, arg)) {
691 debug("Applying options for %.100s", arg);
692 *activep = 1;
693 break;
694 }
695 /* Avoid garbage check below, as strdelim is done. */
696 return 0;
697
698 case oEscapeChar:
699 intptr = &options->escape_char;
700 arg = strdelim(&s);
701 if (!arg || *arg == '\0')
702 fatal("%.200s line %d: Missing argument.", filename, linenum);
703 if (arg[0] == '^' && arg[2] == 0 &&
704 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
705 value = (u_char) arg[1] & 31;
706 else if (strlen(arg) == 1)
707 value = (u_char) arg[0];
708 else if (strcmp(arg, "none") == 0)
709 value = SSH_ESCAPECHAR_NONE;
710 else {
711 fatal("%.200s line %d: Bad escape character.",
e9702f7d 712 filename, linenum);
3c0ef626 713 /* NOTREACHED */
714 value = 0; /* Avoid compiler warning. */
715 }
716 if (*activep && *intptr == -1)
717 *intptr = value;
718 break;
719
7cac2b65 720 case oAddressFamily:
721 arg = strdelim(&s);
722 intptr = &options->address_family;
723 if (strcasecmp(arg, "inet") == 0)
724 value = AF_INET;
725 else if (strcasecmp(arg, "inet6") == 0)
726 value = AF_INET6;
727 else if (strcasecmp(arg, "any") == 0)
728 value = AF_UNSPEC;
729 else
730 fatal("Unsupported AddressFamily \"%s\"", arg);
731 if (*activep && *intptr == -1)
732 *intptr = value;
733 break;
734
bfe49944 735 case oEnableSSHKeysign:
736 intptr = &options->enable_ssh_keysign;
737 goto parse_flag;
738
44a053a3 739 case oDeprecated:
740 debug("%s line %d: Deprecated option \"%s\"",
741 filename, linenum, keyword);
742 return 0;
743
7cac2b65 744 case oUnsupported:
745 error("%s line %d: Unsupported option \"%s\"",
746 filename, linenum, keyword);
747 return 0;
748
3c0ef626 749 default:
750 fatal("process_config_line: Unimplemented opcode %d", opcode);
751 }
752
753 /* Check that there is no garbage at end of line. */
754 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
755 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
e9702f7d 756 filename, linenum, arg);
3c0ef626 757 }
758 return 0;
759}
760
761
762/*
763 * Reads the config file and modifies the options accordingly. Options
764 * should already be initialized before this call. This never returns if
765 * there is an error. If the file does not exist, this returns 0.
766 */
767
768int
769read_config_file(const char *filename, const char *host, Options *options)
770{
771 FILE *f;
772 char line[1024];
773 int active, linenum;
774 int bad_options = 0;
775
776 /* Open the file. */
777 f = fopen(filename, "r");
778 if (!f)
779 return 0;
780
781 debug("Reading configuration data %.200s", filename);
782
783 /*
784 * Mark that we are now processing the options. This flag is turned
785 * on/off by Host specifications.
786 */
787 active = 1;
788 linenum = 0;
789 while (fgets(line, sizeof(line), f)) {
790 /* Update line number counter. */
791 linenum++;
792 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
793 bad_options++;
794 }
795 fclose(f);
796 if (bad_options > 0)
797 fatal("%s: terminating, %d bad configuration options",
e9702f7d 798 filename, bad_options);
3c0ef626 799 return 1;
800}
801
802/*
803 * Initializes options to special values that indicate that they have not yet
804 * been set. Read_config_file will only set options with this value. Options
805 * are processed in the following order: command line, user config file,
806 * system config file. Last, fill_default_options is called.
807 */
808
809void
810initialize_options(Options * options)
811{
812 memset(options, 'X', sizeof(*options));
813 options->forward_agent = -1;
814 options->forward_x11 = -1;
815 options->xauth_location = NULL;
816 options->gateway_ports = -1;
817 options->use_privileged_port = -1;
3c0ef626 818 options->rsa_authentication = -1;
819 options->pubkey_authentication = -1;
820 options->challenge_response_authentication = -1;
7cac2b65 821 options->gss_authentication = -1;
7a056ed1 822 options->gss_keyex = -1;
7cac2b65 823 options->gss_deleg_creds = -1;
3c0ef626 824 options->password_authentication = -1;
825 options->kbd_interactive_authentication = -1;
826 options->kbd_interactive_devices = NULL;
827 options->rhosts_rsa_authentication = -1;
828 options->hostbased_authentication = -1;
3c0ef626 829 options->batch_mode = -1;
830 options->check_host_ip = -1;
831 options->strict_host_key_checking = -1;
832 options->compression = -1;
833 options->keepalives = -1;
834 options->compression_level = -1;
835 options->port = -1;
7cac2b65 836 options->address_family = -1;
3c0ef626 837 options->connection_attempts = -1;
7cac2b65 838 options->connection_timeout = -1;
3c0ef626 839 options->number_of_password_prompts = -1;
840 options->cipher = -1;
841 options->ciphers = NULL;
842 options->macs = NULL;
843 options->hostkeyalgorithms = NULL;
844 options->protocol = SSH_PROTO_UNKNOWN;
845 options->num_identity_files = 0;
846 options->hostname = NULL;
847 options->host_key_alias = NULL;
848 options->proxy_command = NULL;
849 options->user = NULL;
850 options->escape_char = -1;
851 options->system_hostfile = NULL;
852 options->user_hostfile = NULL;
853 options->system_hostfile2 = NULL;
854 options->user_hostfile2 = NULL;
855 options->num_local_forwards = 0;
856 options->num_remote_forwards = 0;
857 options->clear_forwardings = -1;
e9702f7d 858 options->log_level = SYSLOG_LEVEL_NOT_SET;
3c0ef626 859 options->preferred_authentications = NULL;
860 options->bind_address = NULL;
861 options->smartcard_device = NULL;
bfe49944 862 options->enable_ssh_keysign = - 1;
3c0ef626 863 options->no_host_authentication_for_localhost = - 1;
7cac2b65 864 options->rekey_limit = - 1;
865 options->verify_host_key_dns = -1;
3c0ef626 866}
867
868/*
869 * Called after processing other sources of option data, this fills those
870 * options for which no value has been specified with their default values.
871 */
872
873void
874fill_default_options(Options * options)
875{
876 int len;
877
878 if (options->forward_agent == -1)
879 options->forward_agent = 0;
880 if (options->forward_x11 == -1)
881 options->forward_x11 = 0;
3c0ef626 882 if (options->xauth_location == NULL)
883 options->xauth_location = _PATH_XAUTH;
3c0ef626 884 if (options->gateway_ports == -1)
885 options->gateway_ports = 0;
886 if (options->use_privileged_port == -1)
887 options->use_privileged_port = 0;
3c0ef626 888 if (options->rsa_authentication == -1)
889 options->rsa_authentication = 1;
890 if (options->pubkey_authentication == -1)
891 options->pubkey_authentication = 1;
892 if (options->challenge_response_authentication == -1)
893 options->challenge_response_authentication = 1;
5598e598 894 if (options->gss_authentication == -1)
895 options->gss_authentication = 1;
7a056ed1 896 if (options->gss_keyex == -1)
897 options->gss_keyex = 1;
5598e598 898 if (options->gss_deleg_creds == -1)
899 options->gss_deleg_creds = 1;
3c0ef626 900 if (options->password_authentication == -1)
901 options->password_authentication = 1;
902 if (options->kbd_interactive_authentication == -1)
903 options->kbd_interactive_authentication = 1;
904 if (options->rhosts_rsa_authentication == -1)
44a053a3 905 options->rhosts_rsa_authentication = 0;
3c0ef626 906 if (options->hostbased_authentication == -1)
907 options->hostbased_authentication = 0;
3c0ef626 908 if (options->batch_mode == -1)
909 options->batch_mode = 0;
910 if (options->check_host_ip == -1)
911 options->check_host_ip = 1;
912 if (options->strict_host_key_checking == -1)
913 options->strict_host_key_checking = 2; /* 2 is default */
914 if (options->compression == -1)
915 options->compression = 0;
916 if (options->keepalives == -1)
917 options->keepalives = 1;
918 if (options->compression_level == -1)
919 options->compression_level = 6;
920 if (options->port == -1)
921 options->port = 0; /* Filled in ssh_connect. */
7cac2b65 922 if (options->address_family == -1)
923 options->address_family = AF_UNSPEC;
3c0ef626 924 if (options->connection_attempts == -1)
925 options->connection_attempts = 1;
926 if (options->number_of_password_prompts == -1)
927 options->number_of_password_prompts = 3;
928 /* Selected in ssh_login(). */
929 if (options->cipher == -1)
930 options->cipher = SSH_CIPHER_NOT_SET;
931 /* options->ciphers, default set in myproposals.h */
932 /* options->macs, default set in myproposals.h */
933 /* options->hostkeyalgorithms, default set in myproposals.h */
934 if (options->protocol == SSH_PROTO_UNKNOWN)
935 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
936 if (options->num_identity_files == 0) {
937 if (options->protocol & SSH_PROTO_1) {
938 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
939 options->identity_files[options->num_identity_files] =
940 xmalloc(len);
941 snprintf(options->identity_files[options->num_identity_files++],
942 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
943 }
944 if (options->protocol & SSH_PROTO_2) {
945 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
946 options->identity_files[options->num_identity_files] =
947 xmalloc(len);
948 snprintf(options->identity_files[options->num_identity_files++],
949 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
950
951 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
952 options->identity_files[options->num_identity_files] =
953 xmalloc(len);
954 snprintf(options->identity_files[options->num_identity_files++],
955 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
956 }
957 }
958 if (options->escape_char == -1)
959 options->escape_char = '~';
960 if (options->system_hostfile == NULL)
961 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
962 if (options->user_hostfile == NULL)
963 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
964 if (options->system_hostfile2 == NULL)
965 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
966 if (options->user_hostfile2 == NULL)
967 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
e9702f7d 968 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
3c0ef626 969 options->log_level = SYSLOG_LEVEL_INFO;
970 if (options->clear_forwardings == 1)
971 clear_forwardings(options);
972 if (options->no_host_authentication_for_localhost == - 1)
973 options->no_host_authentication_for_localhost = 0;
bfe49944 974 if (options->enable_ssh_keysign == -1)
975 options->enable_ssh_keysign = 0;
7cac2b65 976 if (options->rekey_limit == -1)
977 options->rekey_limit = 0;
978 if (options->verify_host_key_dns == -1)
979 options->verify_host_key_dns = 0;
3c0ef626 980 /* options->proxy_command should not be set by default */
981 /* options->user will be set in the main program if appropriate */
982 /* options->hostname will be set in the main program if appropriate */
983 /* options->host_key_alias should not be set by default */
984 /* options->preferred_authentications will be set in ssh */
985}
This page took 2.993586 seconds and 5 git commands to generate.