5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
10 * Created: Sat Apr 22 00:03:10 1995 ylo
12 * Functions for reading the configuration files.
26 /* Format of the configuration file:
28 # Configuration data is parsed as follows:
29 # 1. command line options
30 # 2. user-specific file
32 # Any configuration value is only changed the first time it is set.
33 # Thus, host-specific definitions should be at the beginning of the
34 # configuration file, and defaults at the end.
36 # Host-specific declarations. These may override anything above. A single
37 # host may match multiple declarations; these are processed in the order
38 # that they are given in.
44 HostName another.host.name.real.org
51 RemoteForward 9999 shadows.cs.hut.fi:9999
57 RhostsAuthentication no
58 PasswordAuthentication no
62 ProxyCommand ssh-proxy %h %p
69 PasswordAuthentication no
71 # Defaults for various options
75 RhostsAuthentication yes
76 PasswordAuthentication yes
78 RhostsRSAAuthentication yes
81 StrictHostKeyChecking yes
83 IdentityFile ~/.ssh/identity
93 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
94 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
97 oKerberosAuthentication,
100 oKerberosTgtPassing, oAFSTokenPassing,
102 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
103 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
104 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
105 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
106 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
107 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol
110 /* Textual representations of the tokens. */
116 { "forwardagent", oForwardAgent },
117 { "forwardx11", oForwardX11 },
118 { "gatewayports", oGatewayPorts },
119 { "useprivilegedport", oUsePrivilegedPort },
120 { "rhostsauthentication", oRhostsAuthentication },
121 { "passwordauthentication", oPasswordAuthentication },
122 { "rsaauthentication", oRSAAuthentication },
123 { "skeyauthentication", oSkeyAuthentication },
125 { "kerberosauthentication", oKerberosAuthentication },
128 { "kerberostgtpassing", oKerberosTgtPassing },
129 { "afstokenpassing", oAFSTokenPassing },
131 { "fallbacktorsh", oFallBackToRsh },
132 { "usersh", oUseRsh },
133 { "identityfile", oIdentityFile },
134 { "hostname", oHostName },
135 { "proxycommand", oProxyCommand },
137 { "cipher", oCipher },
138 { "ciphers", oCiphers },
139 { "protocol", oProtocol },
140 { "remoteforward", oRemoteForward },
141 { "localforward", oLocalForward },
144 { "escapechar", oEscapeChar },
145 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
146 { "globalknownhostsfile", oGlobalKnownHostsFile },
147 { "userknownhostsfile", oUserKnownHostsFile },
148 { "connectionattempts", oConnectionAttempts },
149 { "batchmode", oBatchMode },
150 { "checkhostip", oCheckHostIP },
151 { "stricthostkeychecking", oStrictHostKeyChecking },
152 { "compression", oCompression },
153 { "compressionlevel", oCompressionLevel },
154 { "keepalive", oKeepAlives },
155 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
156 { "tisauthentication", oTISAuthentication },
157 { "loglevel", oLogLevel },
161 /* Characters considered whitespace in strtok calls. */
162 #define WHITESPACE " \t\r\n"
166 * Adds a local TCP/IP port forward to options. Never returns if there is an
171 add_local_forward(Options *options, u_short port, const char *host,
175 extern uid_t original_real_uid;
176 if (port < IPPORT_RESERVED && original_real_uid != 0)
177 fatal("Privileged ports can only be forwarded by root.\n");
178 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
179 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
180 fwd = &options->local_forwards[options->num_local_forwards++];
182 fwd->host = xstrdup(host);
183 fwd->host_port = host_port;
187 * Adds a remote TCP/IP port forward to options. Never returns if there is
192 add_remote_forward(Options *options, u_short port, const char *host,
196 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
197 fatal("Too many remote forwards (max %d).",
198 SSH_MAX_FORWARDS_PER_DIRECTION);
199 fwd = &options->remote_forwards[options->num_remote_forwards++];
201 fwd->host = xstrdup(host);
202 fwd->host_port = host_port;
206 * Returns the number of the token pointed to by cp of length len. Never
207 * returns if the token is not known.
211 parse_token(const char *cp, const char *filename, int linenum)
215 for (i = 0; keywords[i].name; i++)
216 if (strcasecmp(cp, keywords[i].name) == 0)
217 return keywords[i].opcode;
219 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
220 filename, linenum, cp);
225 * Processes a single option line as used in the configuration files. This
226 * only sets those values that have not already been set.
230 process_config_line(Options *options, const char *host,
231 char *line, const char *filename, int linenum,
234 char buf[256], *cp, *string, **charptr, *cp2;
235 int opcode, *intptr, value;
236 u_short fwd_port, fwd_host_port;
238 /* Skip leading whitespace. */
239 cp = line + strspn(line, WHITESPACE);
240 if (!*cp || *cp == '\n' || *cp == '#')
243 /* Get the keyword. (Each line is supposed to begin with a keyword). */
244 cp = strtok(cp, WHITESPACE);
245 opcode = parse_token(cp, filename, linenum);
249 /* don't panic, but count bad options */
253 intptr = &options->forward_agent;
255 cp = strtok(NULL, WHITESPACE);
257 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
258 value = 0; /* To avoid compiler warning... */
259 if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
261 else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
264 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
265 if (*activep && *intptr == -1)
270 intptr = &options->forward_x11;
274 intptr = &options->gateway_ports;
277 case oUsePrivilegedPort:
278 intptr = &options->use_privileged_port;
281 case oRhostsAuthentication:
282 intptr = &options->rhosts_authentication;
285 case oPasswordAuthentication:
286 intptr = &options->password_authentication;
289 case oRSAAuthentication:
290 intptr = &options->rsa_authentication;
293 case oRhostsRSAAuthentication:
294 intptr = &options->rhosts_rsa_authentication;
297 case oTISAuthentication:
298 /* fallthrough, there is no difference on the client side */
299 case oSkeyAuthentication:
300 intptr = &options->skey_authentication;
304 case oKerberosAuthentication:
305 intptr = &options->kerberos_authentication;
310 case oKerberosTgtPassing:
311 intptr = &options->kerberos_tgt_passing;
314 case oAFSTokenPassing:
315 intptr = &options->afs_token_passing;
320 intptr = &options->fallback_to_rsh;
324 intptr = &options->use_rsh;
328 intptr = &options->batch_mode;
332 intptr = &options->check_host_ip;
335 case oStrictHostKeyChecking:
336 intptr = &options->strict_host_key_checking;
337 cp = strtok(NULL, WHITESPACE);
339 fatal("%.200s line %d: Missing yes/no argument.",
341 value = 0; /* To avoid compiler warning... */
342 if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
344 else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
346 else if (strcmp(cp, "ask") == 0)
349 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
350 if (*activep && *intptr == -1)
355 intptr = &options->compression;
359 intptr = &options->keepalives;
362 case oNumberOfPasswordPrompts:
363 intptr = &options->number_of_password_prompts;
366 case oCompressionLevel:
367 intptr = &options->compression_level;
371 cp = strtok(NULL, WHITESPACE);
373 fatal("%.200s line %d: Missing argument.", filename, linenum);
375 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
376 fatal("%.200s line %d: Too many identity files specified (max %d).",
377 filename, linenum, SSH_MAX_IDENTITY_FILES);
378 options->identity_files[options->num_identity_files++] = xstrdup(cp);
383 charptr = &options->user;
385 cp = strtok(NULL, WHITESPACE);
387 fatal("%.200s line %d: Missing argument.", filename, linenum);
388 if (*activep && *charptr == NULL)
389 *charptr = xstrdup(cp);
392 case oGlobalKnownHostsFile:
393 charptr = &options->system_hostfile;
396 case oUserKnownHostsFile:
397 charptr = &options->user_hostfile;
401 charptr = &options->hostname;
405 charptr = &options->proxy_command;
406 string = xstrdup("");
407 while ((cp = strtok(NULL, WHITESPACE)) != NULL) {
408 string = xrealloc(string, strlen(string) + strlen(cp) + 2);
412 if (*activep && *charptr == NULL)
419 intptr = &options->port;
421 cp = strtok(NULL, WHITESPACE);
423 fatal("%.200s line %d: Missing argument.", filename, linenum);
424 if (cp[0] < '0' || cp[0] > '9')
425 fatal("%.200s line %d: Bad number.", filename, linenum);
427 /* Octal, decimal, or hex format? */
428 value = strtol(cp, &cp2, 0);
430 fatal("%.200s line %d: Bad number.", filename, linenum);
431 if (*activep && *intptr == -1)
435 case oConnectionAttempts:
436 intptr = &options->connection_attempts;
440 intptr = &options->cipher;
441 cp = strtok(NULL, WHITESPACE);
442 value = cipher_number(cp);
444 fatal("%.200s line %d: Bad cipher '%s'.",
445 filename, linenum, cp ? cp : "<NONE>");
446 if (*activep && *intptr == -1)
451 cp = strtok(NULL, WHITESPACE);
452 if (!ciphers_valid(cp))
453 fatal("%.200s line %d: Bad cipher spec '%s'.",
454 filename, linenum, cp ? cp : "<NONE>");
455 if (*activep && options->ciphers == NULL)
456 options->ciphers = xstrdup(cp);
460 intptr = &options->protocol;
461 cp = strtok(NULL, WHITESPACE);
462 value = proto_spec(cp);
463 if (value == SSH_PROTO_UNKNOWN)
464 fatal("%.200s line %d: Bad protocol spec '%s'.",
465 filename, linenum, cp ? cp : "<NONE>");
466 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
471 intptr = (int *) &options->log_level;
472 cp = strtok(NULL, WHITESPACE);
473 value = log_level_number(cp);
474 if (value == (LogLevel) - 1)
475 fatal("%.200s line %d: unsupported log level '%s'\n",
476 filename, linenum, cp ? cp : "<NONE>");
477 if (*activep && (LogLevel) * intptr == -1)
478 *intptr = (LogLevel) value;
482 cp = strtok(NULL, WHITESPACE);
484 fatal("%.200s line %d: Missing argument.", filename, linenum);
485 if (cp[0] < '0' || cp[0] > '9')
486 fatal("%.200s line %d: Badly formatted port number.",
489 cp = strtok(NULL, WHITESPACE);
491 fatal("%.200s line %d: Missing second argument.",
493 if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
494 fatal("%.200s line %d: Badly formatted host:port.",
497 add_remote_forward(options, fwd_port, buf, fwd_host_port);
501 cp = strtok(NULL, WHITESPACE);
503 fatal("%.200s line %d: Missing argument.", filename, linenum);
504 if (cp[0] < '0' || cp[0] > '9')
505 fatal("%.200s line %d: Badly formatted port number.",
508 cp = strtok(NULL, WHITESPACE);
510 fatal("%.200s line %d: Missing second argument.",
512 if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
513 fatal("%.200s line %d: Badly formatted host:port.",
516 add_local_forward(options, fwd_port, buf, fwd_host_port);
521 while ((cp = strtok(NULL, WHITESPACE)) != NULL)
522 if (match_pattern(host, cp)) {
523 debug("Applying options for %.100s", cp);
527 /* Avoid garbage check below, as strtok already returned NULL. */
531 intptr = &options->escape_char;
532 cp = strtok(NULL, WHITESPACE);
534 fatal("%.200s line %d: Missing argument.", filename, linenum);
535 if (cp[0] == '^' && cp[2] == 0 &&
536 (unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128)
537 value = (unsigned char) cp[1] & 31;
538 else if (strlen(cp) == 1)
539 value = (unsigned char) cp[0];
540 else if (strcmp(cp, "none") == 0)
543 fatal("%.200s line %d: Bad escape character.",
546 value = 0; /* Avoid compiler warning. */
548 if (*activep && *intptr == -1)
553 fatal("process_config_line: Unimplemented opcode %d", opcode);
556 /* Check that there is no garbage at end of line. */
557 if (strtok(NULL, WHITESPACE) != NULL)
558 fatal("%.200s line %d: garbage at end of line.",
565 * Reads the config file and modifies the options accordingly. Options
566 * should already be initialized before this call. This never returns if
567 * there is an error. If the file does not exist, this returns immediately.
571 read_config_file(const char *filename, const char *host, Options *options)
579 f = fopen(filename, "r");
583 debug("Reading configuration data %.200s", filename);
586 * Mark that we are now processing the options. This flag is turned
587 * on/off by Host specifications.
591 while (fgets(line, sizeof(line), f)) {
592 /* Update line number counter. */
594 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
599 fatal("%s: terminating, %d bad configuration options\n",
600 filename, bad_options);
604 * Initializes options to special values that indicate that they have not yet
605 * been set. Read_config_file will only set options with this value. Options
606 * are processed in the following order: command line, user config file,
607 * system config file. Last, fill_default_options is called.
611 initialize_options(Options * options)
613 memset(options, 'X', sizeof(*options));
614 options->forward_agent = -1;
615 options->forward_x11 = -1;
616 options->gateway_ports = -1;
617 options->use_privileged_port = -1;
618 options->rhosts_authentication = -1;
619 options->rsa_authentication = -1;
620 options->skey_authentication = -1;
622 options->kerberos_authentication = -1;
625 options->kerberos_tgt_passing = -1;
626 options->afs_token_passing = -1;
628 options->password_authentication = -1;
629 options->rhosts_rsa_authentication = -1;
630 options->fallback_to_rsh = -1;
631 options->use_rsh = -1;
632 options->batch_mode = -1;
633 options->check_host_ip = -1;
634 options->strict_host_key_checking = -1;
635 options->compression = -1;
636 options->keepalives = -1;
637 options->compression_level = -1;
639 options->connection_attempts = -1;
640 options->number_of_password_prompts = -1;
641 options->cipher = -1;
642 options->ciphers = NULL;
643 options->protocol = SSH_PROTO_UNKNOWN;
644 options->num_identity_files = 0;
645 options->hostname = NULL;
646 options->proxy_command = NULL;
647 options->user = NULL;
648 options->escape_char = -1;
649 options->system_hostfile = NULL;
650 options->user_hostfile = NULL;
651 options->num_local_forwards = 0;
652 options->num_remote_forwards = 0;
653 options->log_level = (LogLevel) - 1;
657 * Called after processing other sources of option data, this fills those
658 * options for which no value has been specified with their default values.
662 fill_default_options(Options * options)
664 if (options->forward_agent == -1)
665 options->forward_agent = 1;
666 if (options->forward_x11 == -1)
667 options->forward_x11 = 0;
668 if (options->gateway_ports == -1)
669 options->gateway_ports = 0;
670 if (options->use_privileged_port == -1)
671 options->use_privileged_port = 1;
672 if (options->rhosts_authentication == -1)
673 options->rhosts_authentication = 1;
674 if (options->rsa_authentication == -1)
675 options->rsa_authentication = 1;
676 if (options->skey_authentication == -1)
677 options->skey_authentication = 0;
679 if (options->kerberos_authentication == -1)
680 options->kerberos_authentication = 1;
683 if (options->kerberos_tgt_passing == -1)
684 options->kerberos_tgt_passing = 1;
685 if (options->afs_token_passing == -1)
686 options->afs_token_passing = 1;
688 if (options->password_authentication == -1)
689 options->password_authentication = 1;
690 if (options->rhosts_rsa_authentication == -1)
691 options->rhosts_rsa_authentication = 1;
692 if (options->fallback_to_rsh == -1)
693 options->fallback_to_rsh = 1;
694 if (options->use_rsh == -1)
695 options->use_rsh = 0;
696 if (options->batch_mode == -1)
697 options->batch_mode = 0;
698 if (options->check_host_ip == -1)
699 options->check_host_ip = 1;
700 if (options->strict_host_key_checking == -1)
701 options->strict_host_key_checking = 2; /* 2 is default */
702 if (options->compression == -1)
703 options->compression = 0;
704 if (options->keepalives == -1)
705 options->keepalives = 1;
706 if (options->compression_level == -1)
707 options->compression_level = 6;
708 if (options->port == -1)
709 options->port = 0; /* Filled in ssh_connect. */
710 if (options->connection_attempts == -1)
711 options->connection_attempts = 4;
712 if (options->number_of_password_prompts == -1)
713 options->number_of_password_prompts = 3;
714 /* Selected in ssh_login(). */
715 if (options->cipher == -1)
716 options->cipher = SSH_CIPHER_NOT_SET;
717 if (options->protocol == SSH_PROTO_UNKNOWN)
718 options->protocol = SSH_PROTO_1;
719 if (options->num_identity_files == 0) {
720 options->identity_files[0] =
721 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
722 sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
723 options->num_identity_files = 1;
725 if (options->escape_char == -1)
726 options->escape_char = '~';
727 if (options->system_hostfile == NULL)
728 options->system_hostfile = SSH_SYSTEM_HOSTFILE;
729 if (options->user_hostfile == NULL)
730 options->user_hostfile = SSH_USER_HOSTFILE;
731 if (options->log_level == (LogLevel) - 1)
732 options->log_level = SYSLOG_LEVEL_INFO;
733 /* options->proxy_command should not be set by default */
734 /* options->user will be set in the main program if appropriate */
735 /* options->hostname will be set in the main program if appropriate */