2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * Functions for reading the configuration files.
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".
15 RCSID("$OpenBSD: readconf.c,v 1.70 2001/04/02 14:20:23 stevesk Exp $");
21 #include "pathnames.h"
29 /* Format of the configuration file:
31 # Configuration data is parsed as follows:
32 # 1. command line options
33 # 2. user-specific 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.
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.
47 HostName another.host.name.real.org
54 RemoteForward 9999 shadows.cs.hut.fi:9999
60 RhostsAuthentication no
61 PasswordAuthentication no
65 ProxyCommand ssh-proxy %h %p
72 PasswordAuthentication no
74 # Defaults for various options
78 RhostsAuthentication yes
79 PasswordAuthentication yes
81 RhostsRSAAuthentication yes
84 StrictHostKeyChecking yes
86 IdentityFile ~/.ssh/identity
96 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
97 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
98 oChallengeResponseAuthentication, oXAuthLocation,
100 oKerberosAuthentication,
103 oKerberosTgtPassing, oAFSTokenPassing,
105 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
106 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
107 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
108 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
109 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
110 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
111 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
112 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
113 oPreferredAuthentications
116 /* Textual representations of the tokens. */
122 { "forwardagent", oForwardAgent },
123 { "forwardx11", oForwardX11 },
124 { "xauthlocation", oXAuthLocation },
125 { "gatewayports", oGatewayPorts },
126 { "useprivilegedport", oUsePrivilegedPort },
127 { "rhostsauthentication", oRhostsAuthentication },
128 { "passwordauthentication", oPasswordAuthentication },
129 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
130 { "kbdinteractivedevices", oKbdInteractiveDevices },
131 { "rsaauthentication", oRSAAuthentication },
132 { "pubkeyauthentication", oPubkeyAuthentication },
133 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
134 { "challengeresponseauthentication", oChallengeResponseAuthentication },
135 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
136 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
138 { "kerberosauthentication", oKerberosAuthentication },
141 { "kerberostgtpassing", oKerberosTgtPassing },
142 { "afstokenpassing", oAFSTokenPassing },
144 { "fallbacktorsh", oFallBackToRsh },
145 { "usersh", oUseRsh },
146 { "identityfile", oIdentityFile },
147 { "identityfile2", oIdentityFile }, /* alias */
148 { "hostname", oHostName },
149 { "hostkeyalias", oHostKeyAlias },
150 { "proxycommand", oProxyCommand },
152 { "cipher", oCipher },
153 { "ciphers", oCiphers },
155 { "protocol", oProtocol },
156 { "remoteforward", oRemoteForward },
157 { "localforward", oLocalForward },
160 { "escapechar", oEscapeChar },
161 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
162 { "globalknownhostsfile", oGlobalKnownHostsFile },
163 { "userknownhostsfile", oUserKnownHostsFile },
164 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
165 { "userknownhostsfile2", oUserKnownHostsFile2 },
166 { "connectionattempts", oConnectionAttempts },
167 { "batchmode", oBatchMode },
168 { "checkhostip", oCheckHostIP },
169 { "stricthostkeychecking", oStrictHostKeyChecking },
170 { "compression", oCompression },
171 { "compressionlevel", oCompressionLevel },
172 { "keepalive", oKeepAlives },
173 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
174 { "loglevel", oLogLevel },
175 { "preferredauthentications", oPreferredAuthentications },
180 * Adds a local TCP/IP port forward to options. Never returns if there is an
185 add_local_forward(Options *options, u_short port, const char *host,
190 extern uid_t original_real_uid;
191 if (port < IPPORT_RESERVED && original_real_uid != 0)
192 fatal("Privileged ports can only be forwarded by root.");
194 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
195 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
196 fwd = &options->local_forwards[options->num_local_forwards++];
198 fwd->host = xstrdup(host);
199 fwd->host_port = host_port;
203 * Adds a remote TCP/IP port forward to options. Never returns if there is
208 add_remote_forward(Options *options, u_short port, const char *host,
212 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
213 fatal("Too many remote forwards (max %d).",
214 SSH_MAX_FORWARDS_PER_DIRECTION);
215 fwd = &options->remote_forwards[options->num_remote_forwards++];
217 fwd->host = xstrdup(host);
218 fwd->host_port = host_port;
222 * Returns the number of the token pointed to by cp or oBadOption.
226 parse_token(const char *cp, const char *filename, int linenum)
230 for (i = 0; keywords[i].name; i++)
231 if (strcasecmp(cp, keywords[i].name) == 0)
232 return keywords[i].opcode;
234 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
235 filename, linenum, cp);
240 * Processes a single option line as used in the configuration files. This
241 * only sets those values that have not already been set.
245 process_config_line(Options *options, const char *host,
246 char *line, const char *filename, int linenum,
249 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
250 int opcode, *intptr, value;
251 u_short fwd_port, fwd_host_port;
254 /* Get the keyword. (Each line is supposed to begin with a keyword). */
255 keyword = strdelim(&s);
256 /* Ignore leading whitespace. */
257 if (*keyword == '\0')
258 keyword = strdelim(&s);
259 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
262 opcode = parse_token(keyword, filename, linenum);
266 /* don't panic, but count bad options */
270 intptr = &options->forward_agent;
273 if (!arg || *arg == '\0')
274 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
275 value = 0; /* To avoid compiler warning... */
276 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
278 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
281 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
282 if (*activep && *intptr == -1)
287 intptr = &options->forward_x11;
291 intptr = &options->gateway_ports;
294 case oUsePrivilegedPort:
295 intptr = &options->use_privileged_port;
298 case oRhostsAuthentication:
299 intptr = &options->rhosts_authentication;
302 case oPasswordAuthentication:
303 intptr = &options->password_authentication;
306 case oKbdInteractiveAuthentication:
307 intptr = &options->kbd_interactive_authentication;
310 case oKbdInteractiveDevices:
311 charptr = &options->kbd_interactive_devices;
314 case oPubkeyAuthentication:
315 intptr = &options->pubkey_authentication;
318 case oRSAAuthentication:
319 intptr = &options->rsa_authentication;
322 case oRhostsRSAAuthentication:
323 intptr = &options->rhosts_rsa_authentication;
326 case oChallengeResponseAuthentication:
327 intptr = &options->challenge_reponse_authentication;
331 case oKerberosAuthentication:
332 intptr = &options->kerberos_authentication;
337 case oKerberosTgtPassing:
338 intptr = &options->kerberos_tgt_passing;
341 case oAFSTokenPassing:
342 intptr = &options->afs_token_passing;
347 intptr = &options->fallback_to_rsh;
351 intptr = &options->use_rsh;
355 intptr = &options->batch_mode;
359 intptr = &options->check_host_ip;
362 case oStrictHostKeyChecking:
363 intptr = &options->strict_host_key_checking;
365 if (!arg || *arg == '\0')
366 fatal("%.200s line %d: Missing yes/no/ask argument.",
368 value = 0; /* To avoid compiler warning... */
369 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
371 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
373 else if (strcmp(arg, "ask") == 0)
376 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
377 if (*activep && *intptr == -1)
382 intptr = &options->compression;
386 intptr = &options->keepalives;
389 case oNumberOfPasswordPrompts:
390 intptr = &options->number_of_password_prompts;
393 case oCompressionLevel:
394 intptr = &options->compression_level;
399 if (!arg || *arg == '\0')
400 fatal("%.200s line %d: Missing argument.", filename, linenum);
402 intptr = &options->num_identity_files;
403 if (*intptr >= SSH_MAX_IDENTITY_FILES)
404 fatal("%.200s line %d: Too many identity files specified (max %d).",
405 filename, linenum, SSH_MAX_IDENTITY_FILES);
406 charptr = &options->identity_files[*intptr];
407 *charptr = xstrdup(arg);
408 *intptr = *intptr + 1;
413 charptr=&options->xauth_location;
417 charptr = &options->user;
420 if (!arg || *arg == '\0')
421 fatal("%.200s line %d: Missing argument.", filename, linenum);
422 if (*activep && *charptr == NULL)
423 *charptr = xstrdup(arg);
426 case oGlobalKnownHostsFile:
427 charptr = &options->system_hostfile;
430 case oUserKnownHostsFile:
431 charptr = &options->user_hostfile;
434 case oGlobalKnownHostsFile2:
435 charptr = &options->system_hostfile2;
438 case oUserKnownHostsFile2:
439 charptr = &options->user_hostfile2;
443 charptr = &options->hostname;
447 charptr = &options->host_key_alias;
450 case oPreferredAuthentications:
451 charptr = &options->preferred_authentications;
455 charptr = &options->proxy_command;
456 string = xstrdup("");
457 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
458 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
462 if (*activep && *charptr == NULL)
469 intptr = &options->port;
472 if (!arg || *arg == '\0')
473 fatal("%.200s line %d: Missing argument.", filename, linenum);
474 if (arg[0] < '0' || arg[0] > '9')
475 fatal("%.200s line %d: Bad number.", filename, linenum);
477 /* Octal, decimal, or hex format? */
478 value = strtol(arg, &endofnumber, 0);
479 if (arg == endofnumber)
480 fatal("%.200s line %d: Bad number.", filename, linenum);
481 if (*activep && *intptr == -1)
485 case oConnectionAttempts:
486 intptr = &options->connection_attempts;
490 intptr = &options->cipher;
492 if (!arg || *arg == '\0')
493 fatal("%.200s line %d: Missing argument.", filename, linenum);
494 value = cipher_number(arg);
496 fatal("%.200s line %d: Bad cipher '%s'.",
497 filename, linenum, arg ? arg : "<NONE>");
498 if (*activep && *intptr == -1)
504 if (!arg || *arg == '\0')
505 fatal("%.200s line %d: Missing argument.", filename, linenum);
506 if (!ciphers_valid(arg))
507 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
508 filename, linenum, arg ? arg : "<NONE>");
509 if (*activep && options->ciphers == NULL)
510 options->ciphers = xstrdup(arg);
515 if (!arg || *arg == '\0')
516 fatal("%.200s line %d: Missing argument.", filename, linenum);
518 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
519 filename, linenum, arg ? arg : "<NONE>");
520 if (*activep && options->macs == NULL)
521 options->macs = xstrdup(arg);
525 intptr = &options->protocol;
527 if (!arg || *arg == '\0')
528 fatal("%.200s line %d: Missing argument.", filename, linenum);
529 value = proto_spec(arg);
530 if (value == SSH_PROTO_UNKNOWN)
531 fatal("%.200s line %d: Bad protocol spec '%s'.",
532 filename, linenum, arg ? arg : "<NONE>");
533 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
538 intptr = (int *) &options->log_level;
540 value = log_level_number(arg);
541 if (value == (LogLevel) - 1)
542 fatal("%.200s line %d: unsupported log level '%s'",
543 filename, linenum, arg ? arg : "<NONE>");
544 if (*activep && (LogLevel) * intptr == -1)
545 *intptr = (LogLevel) value;
550 if (!arg || *arg == '\0')
551 fatal("%.200s line %d: Missing argument.", filename, linenum);
552 if (arg[0] < '0' || arg[0] > '9')
553 fatal("%.200s line %d: Badly formatted port number.",
555 fwd_port = atoi(arg);
557 if (!arg || *arg == '\0')
558 fatal("%.200s line %d: Missing second argument.",
560 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
561 fatal("%.200s line %d: Badly formatted host:port.",
564 add_remote_forward(options, fwd_port, buf, fwd_host_port);
569 if (!arg || *arg == '\0')
570 fatal("%.200s line %d: Missing argument.", filename, linenum);
571 if (arg[0] < '0' || arg[0] > '9')
572 fatal("%.200s line %d: Badly formatted port number.",
574 fwd_port = atoi(arg);
576 if (!arg || *arg == '\0')
577 fatal("%.200s line %d: Missing second argument.",
579 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
580 fatal("%.200s line %d: Badly formatted host:port.",
583 add_local_forward(options, fwd_port, buf, fwd_host_port);
588 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
589 if (match_pattern(host, arg)) {
590 debug("Applying options for %.100s", arg);
594 /* Avoid garbage check below, as strdelim is done. */
598 intptr = &options->escape_char;
600 if (!arg || *arg == '\0')
601 fatal("%.200s line %d: Missing argument.", filename, linenum);
602 if (arg[0] == '^' && arg[2] == 0 &&
603 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
604 value = (u_char) arg[1] & 31;
605 else if (strlen(arg) == 1)
606 value = (u_char) arg[0];
607 else if (strcmp(arg, "none") == 0)
610 fatal("%.200s line %d: Bad escape character.",
613 value = 0; /* Avoid compiler warning. */
615 if (*activep && *intptr == -1)
620 fatal("process_config_line: Unimplemented opcode %d", opcode);
623 /* Check that there is no garbage at end of line. */
624 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
625 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
626 filename, linenum, arg);
633 * Reads the config file and modifies the options accordingly. Options
634 * should already be initialized before this call. This never returns if
635 * there is an error. If the file does not exist, this returns immediately.
639 read_config_file(const char *filename, const char *host, Options *options)
647 f = fopen(filename, "r");
651 debug("Reading configuration data %.200s", filename);
654 * Mark that we are now processing the options. This flag is turned
655 * on/off by Host specifications.
659 while (fgets(line, sizeof(line), f)) {
660 /* Update line number counter. */
662 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
667 fatal("%s: terminating, %d bad configuration options",
668 filename, bad_options);
672 * Initializes options to special values that indicate that they have not yet
673 * been set. Read_config_file will only set options with this value. Options
674 * are processed in the following order: command line, user config file,
675 * system config file. Last, fill_default_options is called.
679 initialize_options(Options * options)
681 memset(options, 'X', sizeof(*options));
682 options->forward_agent = -1;
683 options->forward_x11 = -1;
684 options->xauth_location = NULL;
685 options->gateway_ports = -1;
686 options->use_privileged_port = -1;
687 options->rhosts_authentication = -1;
688 options->rsa_authentication = -1;
689 options->pubkey_authentication = -1;
690 options->challenge_reponse_authentication = -1;
692 options->kerberos_authentication = -1;
695 options->kerberos_tgt_passing = -1;
696 options->afs_token_passing = -1;
698 options->password_authentication = -1;
699 options->kbd_interactive_authentication = -1;
700 options->kbd_interactive_devices = NULL;
701 options->rhosts_rsa_authentication = -1;
702 options->fallback_to_rsh = -1;
703 options->use_rsh = -1;
704 options->batch_mode = -1;
705 options->check_host_ip = -1;
706 options->strict_host_key_checking = -1;
707 options->compression = -1;
708 options->keepalives = -1;
709 options->compression_level = -1;
711 options->connection_attempts = -1;
712 options->number_of_password_prompts = -1;
713 options->cipher = -1;
714 options->ciphers = NULL;
715 options->macs = NULL;
716 options->protocol = SSH_PROTO_UNKNOWN;
717 options->num_identity_files = 0;
718 options->hostname = NULL;
719 options->host_key_alias = NULL;
720 options->proxy_command = NULL;
721 options->user = NULL;
722 options->escape_char = -1;
723 options->system_hostfile = NULL;
724 options->user_hostfile = NULL;
725 options->system_hostfile2 = NULL;
726 options->user_hostfile2 = NULL;
727 options->num_local_forwards = 0;
728 options->num_remote_forwards = 0;
729 options->log_level = (LogLevel) - 1;
730 options->preferred_authentications = NULL;
734 * Called after processing other sources of option data, this fills those
735 * options for which no value has been specified with their default values.
739 fill_default_options(Options * options)
743 if (options->forward_agent == -1)
744 options->forward_agent = 0;
745 if (options->forward_x11 == -1)
746 options->forward_x11 = 0;
748 if (options->xauth_location == NULL)
749 options->xauth_location = XAUTH_PATH;
750 #endif /* XAUTH_PATH */
751 if (options->gateway_ports == -1)
752 options->gateway_ports = 0;
753 if (options->use_privileged_port == -1)
754 options->use_privileged_port = 0;
755 if (options->rhosts_authentication == -1)
756 options->rhosts_authentication = 1;
757 if (options->rsa_authentication == -1)
758 options->rsa_authentication = 1;
759 if (options->pubkey_authentication == -1)
760 options->pubkey_authentication = 1;
761 if (options->challenge_reponse_authentication == -1)
762 options->challenge_reponse_authentication = 0;
764 if (options->kerberos_authentication == -1)
765 options->kerberos_authentication = 1;
768 if (options->kerberos_tgt_passing == -1)
769 options->kerberos_tgt_passing = 1;
770 if (options->afs_token_passing == -1)
771 options->afs_token_passing = 1;
773 if (options->password_authentication == -1)
774 options->password_authentication = 1;
775 if (options->kbd_interactive_authentication == -1)
776 options->kbd_interactive_authentication = 1;
777 if (options->rhosts_rsa_authentication == -1)
778 options->rhosts_rsa_authentication = 1;
779 if (options->fallback_to_rsh == -1)
780 options->fallback_to_rsh = 0;
781 if (options->use_rsh == -1)
782 options->use_rsh = 0;
783 if (options->batch_mode == -1)
784 options->batch_mode = 0;
785 if (options->check_host_ip == -1)
786 options->check_host_ip = 1;
787 if (options->strict_host_key_checking == -1)
788 options->strict_host_key_checking = 2; /* 2 is default */
789 if (options->compression == -1)
790 options->compression = 0;
791 if (options->keepalives == -1)
792 options->keepalives = 1;
793 if (options->compression_level == -1)
794 options->compression_level = 6;
795 if (options->port == -1)
796 options->port = 0; /* Filled in ssh_connect. */
797 if (options->connection_attempts == -1)
798 options->connection_attempts = 4;
799 if (options->number_of_password_prompts == -1)
800 options->number_of_password_prompts = 3;
801 /* Selected in ssh_login(). */
802 if (options->cipher == -1)
803 options->cipher = SSH_CIPHER_NOT_SET;
804 /* options->ciphers, default set in myproposals.h */
805 /* options->macs, default set in myproposals.h */
806 if (options->protocol == SSH_PROTO_UNKNOWN)
807 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
808 if (options->num_identity_files == 0) {
809 if (options->protocol & SSH_PROTO_1) {
810 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
811 options->identity_files[options->num_identity_files] =
813 snprintf(options->identity_files[options->num_identity_files++],
814 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
816 if (options->protocol & SSH_PROTO_2) {
817 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
818 options->identity_files[options->num_identity_files] =
820 snprintf(options->identity_files[options->num_identity_files++],
821 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
823 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
824 options->identity_files[options->num_identity_files] =
826 snprintf(options->identity_files[options->num_identity_files++],
827 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
830 if (options->escape_char == -1)
831 options->escape_char = '~';
832 if (options->system_hostfile == NULL)
833 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
834 if (options->user_hostfile == NULL)
835 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
836 if (options->system_hostfile2 == NULL)
837 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
838 if (options->user_hostfile2 == NULL)
839 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
840 if (options->log_level == (LogLevel) - 1)
841 options->log_level = SYSLOG_LEVEL_INFO;
842 /* options->proxy_command should not be set by default */
843 /* options->user will be set in the main program if appropriate */
844 /* options->hostname will be set in the main program if appropriate */
845 /* options->host_key_alias should not be set by default */
846 /* options->preferred_authentications will be set in ssh */