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.66 2001/03/10 12:53:52 deraadt 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
115 /* Textual representations of the tokens. */
121 { "forwardagent", oForwardAgent },
122 { "forwardx11", oForwardX11 },
123 { "xauthlocation", oXAuthLocation },
124 { "gatewayports", oGatewayPorts },
125 { "useprivilegedport", oUsePrivilegedPort },
126 { "rhostsauthentication", oRhostsAuthentication },
127 { "passwordauthentication", oPasswordAuthentication },
128 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
129 { "kbdinteractivedevices", oKbdInteractiveDevices },
130 { "rsaauthentication", oRSAAuthentication },
131 { "pubkeyauthentication", oPubkeyAuthentication },
132 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
133 { "challengeresponseauthentication", oChallengeResponseAuthentication },
134 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
135 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
137 { "kerberosauthentication", oKerberosAuthentication },
140 { "kerberostgtpassing", oKerberosTgtPassing },
141 { "afstokenpassing", oAFSTokenPassing },
143 { "fallbacktorsh", oFallBackToRsh },
144 { "usersh", oUseRsh },
145 { "identityfile", oIdentityFile },
146 { "identityfile2", oIdentityFile }, /* alias */
147 { "hostname", oHostName },
148 { "hostkeyalias", oHostKeyAlias },
149 { "proxycommand", oProxyCommand },
151 { "cipher", oCipher },
152 { "ciphers", oCiphers },
154 { "protocol", oProtocol },
155 { "remoteforward", oRemoteForward },
156 { "localforward", oLocalForward },
159 { "escapechar", oEscapeChar },
160 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
161 { "globalknownhostsfile", oGlobalKnownHostsFile },
162 { "userknownhostsfile", oUserKnownHostsFile },
163 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
164 { "userknownhostsfile2", oUserKnownHostsFile2 },
165 { "connectionattempts", oConnectionAttempts },
166 { "batchmode", oBatchMode },
167 { "checkhostip", oCheckHostIP },
168 { "stricthostkeychecking", oStrictHostKeyChecking },
169 { "compression", oCompression },
170 { "compressionlevel", oCompressionLevel },
171 { "keepalive", oKeepAlives },
172 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
173 { "loglevel", oLogLevel },
178 * Adds a local TCP/IP port forward to options. Never returns if there is an
183 add_local_forward(Options *options, u_short port, const char *host,
188 extern uid_t original_real_uid;
189 if (port < IPPORT_RESERVED && original_real_uid != 0)
190 fatal("Privileged ports can only be forwarded by root.");
192 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
193 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
194 fwd = &options->local_forwards[options->num_local_forwards++];
196 fwd->host = xstrdup(host);
197 fwd->host_port = host_port;
201 * Adds a remote TCP/IP port forward to options. Never returns if there is
206 add_remote_forward(Options *options, u_short port, const char *host,
210 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
211 fatal("Too many remote forwards (max %d).",
212 SSH_MAX_FORWARDS_PER_DIRECTION);
213 fwd = &options->remote_forwards[options->num_remote_forwards++];
215 fwd->host = xstrdup(host);
216 fwd->host_port = host_port;
220 * Returns the number of the token pointed to by cp of length len. Never
221 * returns if the token is not known.
225 parse_token(const char *cp, const char *filename, int linenum)
229 for (i = 0; keywords[i].name; i++)
230 if (strcasecmp(cp, keywords[i].name) == 0)
231 return keywords[i].opcode;
233 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
234 filename, linenum, cp);
239 * Processes a single option line as used in the configuration files. This
240 * only sets those values that have not already been set.
244 process_config_line(Options *options, const char *host,
245 char *line, const char *filename, int linenum,
248 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
249 int opcode, *intptr, value;
250 u_short fwd_port, fwd_host_port;
253 /* Get the keyword. (Each line is supposed to begin with a keyword). */
254 keyword = strdelim(&s);
255 /* Ignore leading whitespace. */
256 if (*keyword == '\0')
257 keyword = strdelim(&s);
258 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
261 opcode = parse_token(keyword, filename, linenum);
265 /* don't panic, but count bad options */
269 intptr = &options->forward_agent;
272 if (!arg || *arg == '\0')
273 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
274 value = 0; /* To avoid compiler warning... */
275 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
277 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
280 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
281 if (*activep && *intptr == -1)
286 intptr = &options->forward_x11;
290 intptr = &options->gateway_ports;
293 case oUsePrivilegedPort:
294 intptr = &options->use_privileged_port;
297 case oRhostsAuthentication:
298 intptr = &options->rhosts_authentication;
301 case oPasswordAuthentication:
302 intptr = &options->password_authentication;
305 case oKbdInteractiveAuthentication:
306 intptr = &options->kbd_interactive_authentication;
309 case oKbdInteractiveDevices:
310 charptr = &options->kbd_interactive_devices;
313 case oPubkeyAuthentication:
314 intptr = &options->pubkey_authentication;
317 case oRSAAuthentication:
318 intptr = &options->rsa_authentication;
321 case oRhostsRSAAuthentication:
322 intptr = &options->rhosts_rsa_authentication;
325 case oChallengeResponseAuthentication:
326 intptr = &options->challenge_reponse_authentication;
330 case oKerberosAuthentication:
331 intptr = &options->kerberos_authentication;
336 case oKerberosTgtPassing:
337 intptr = &options->kerberos_tgt_passing;
340 case oAFSTokenPassing:
341 intptr = &options->afs_token_passing;
346 intptr = &options->fallback_to_rsh;
350 intptr = &options->use_rsh;
354 intptr = &options->batch_mode;
358 intptr = &options->check_host_ip;
361 case oStrictHostKeyChecking:
362 intptr = &options->strict_host_key_checking;
364 if (!arg || *arg == '\0')
365 fatal("%.200s line %d: Missing yes/no/ask argument.",
367 value = 0; /* To avoid compiler warning... */
368 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
370 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
372 else if (strcmp(arg, "ask") == 0)
375 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
376 if (*activep && *intptr == -1)
381 intptr = &options->compression;
385 intptr = &options->keepalives;
388 case oNumberOfPasswordPrompts:
389 intptr = &options->number_of_password_prompts;
392 case oCompressionLevel:
393 intptr = &options->compression_level;
398 if (!arg || *arg == '\0')
399 fatal("%.200s line %d: Missing argument.", filename, linenum);
401 intptr = &options->num_identity_files;
402 if (*intptr >= SSH_MAX_IDENTITY_FILES)
403 fatal("%.200s line %d: Too many identity files specified (max %d).",
404 filename, linenum, SSH_MAX_IDENTITY_FILES);
405 charptr = &options->identity_files[*intptr];
406 *charptr = xstrdup(arg);
407 *intptr = *intptr + 1;
412 charptr=&options->xauth_location;
416 charptr = &options->user;
419 if (!arg || *arg == '\0')
420 fatal("%.200s line %d: Missing argument.", filename, linenum);
421 if (*activep && *charptr == NULL)
422 *charptr = xstrdup(arg);
425 case oGlobalKnownHostsFile:
426 charptr = &options->system_hostfile;
429 case oUserKnownHostsFile:
430 charptr = &options->user_hostfile;
433 case oGlobalKnownHostsFile2:
434 charptr = &options->system_hostfile2;
437 case oUserKnownHostsFile2:
438 charptr = &options->user_hostfile2;
442 charptr = &options->hostname;
446 charptr = &options->host_key_alias;
450 charptr = &options->proxy_command;
451 string = xstrdup("");
452 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
453 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
457 if (*activep && *charptr == NULL)
464 intptr = &options->port;
467 if (!arg || *arg == '\0')
468 fatal("%.200s line %d: Missing argument.", filename, linenum);
469 if (arg[0] < '0' || arg[0] > '9')
470 fatal("%.200s line %d: Bad number.", filename, linenum);
472 /* Octal, decimal, or hex format? */
473 value = strtol(arg, &endofnumber, 0);
474 if (arg == endofnumber)
475 fatal("%.200s line %d: Bad number.", filename, linenum);
476 if (*activep && *intptr == -1)
480 case oConnectionAttempts:
481 intptr = &options->connection_attempts;
485 intptr = &options->cipher;
487 if (!arg || *arg == '\0')
488 fatal("%.200s line %d: Missing argument.", filename, linenum);
489 value = cipher_number(arg);
491 fatal("%.200s line %d: Bad cipher '%s'.",
492 filename, linenum, arg ? arg : "<NONE>");
493 if (*activep && *intptr == -1)
499 if (!arg || *arg == '\0')
500 fatal("%.200s line %d: Missing argument.", filename, linenum);
501 if (!ciphers_valid(arg))
502 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
503 filename, linenum, arg ? arg : "<NONE>");
504 if (*activep && options->ciphers == NULL)
505 options->ciphers = xstrdup(arg);
510 if (!arg || *arg == '\0')
511 fatal("%.200s line %d: Missing argument.", filename, linenum);
513 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
514 filename, linenum, arg ? arg : "<NONE>");
515 if (*activep && options->macs == NULL)
516 options->macs = xstrdup(arg);
520 intptr = &options->protocol;
522 if (!arg || *arg == '\0')
523 fatal("%.200s line %d: Missing argument.", filename, linenum);
524 value = proto_spec(arg);
525 if (value == SSH_PROTO_UNKNOWN)
526 fatal("%.200s line %d: Bad protocol spec '%s'.",
527 filename, linenum, arg ? arg : "<NONE>");
528 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
533 intptr = (int *) &options->log_level;
535 value = log_level_number(arg);
536 if (value == (LogLevel) - 1)
537 fatal("%.200s line %d: unsupported log level '%s'",
538 filename, linenum, arg ? arg : "<NONE>");
539 if (*activep && (LogLevel) * intptr == -1)
540 *intptr = (LogLevel) value;
545 if (!arg || *arg == '\0')
546 fatal("%.200s line %d: Missing argument.", filename, linenum);
547 if (arg[0] < '0' || arg[0] > '9')
548 fatal("%.200s line %d: Badly formatted port number.",
550 fwd_port = atoi(arg);
552 if (!arg || *arg == '\0')
553 fatal("%.200s line %d: Missing second argument.",
555 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
556 fatal("%.200s line %d: Badly formatted host:port.",
559 add_remote_forward(options, fwd_port, buf, fwd_host_port);
564 if (!arg || *arg == '\0')
565 fatal("%.200s line %d: Missing argument.", filename, linenum);
566 if (arg[0] < '0' || arg[0] > '9')
567 fatal("%.200s line %d: Badly formatted port number.",
569 fwd_port = atoi(arg);
571 if (!arg || *arg == '\0')
572 fatal("%.200s line %d: Missing second argument.",
574 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
575 fatal("%.200s line %d: Badly formatted host:port.",
578 add_local_forward(options, fwd_port, buf, fwd_host_port);
583 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
584 if (match_pattern(host, arg)) {
585 debug("Applying options for %.100s", arg);
589 /* Avoid garbage check below, as strdelim is done. */
593 intptr = &options->escape_char;
595 if (!arg || *arg == '\0')
596 fatal("%.200s line %d: Missing argument.", filename, linenum);
597 if (arg[0] == '^' && arg[2] == 0 &&
598 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
599 value = (u_char) arg[1] & 31;
600 else if (strlen(arg) == 1)
601 value = (u_char) arg[0];
602 else if (strcmp(arg, "none") == 0)
605 fatal("%.200s line %d: Bad escape character.",
608 value = 0; /* Avoid compiler warning. */
610 if (*activep && *intptr == -1)
615 fatal("process_config_line: Unimplemented opcode %d", opcode);
618 /* Check that there is no garbage at end of line. */
619 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
620 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
621 filename, linenum, arg);
628 * Reads the config file and modifies the options accordingly. Options
629 * should already be initialized before this call. This never returns if
630 * there is an error. If the file does not exist, this returns immediately.
634 read_config_file(const char *filename, const char *host, Options *options)
642 f = fopen(filename, "r");
646 debug("Reading configuration data %.200s", filename);
649 * Mark that we are now processing the options. This flag is turned
650 * on/off by Host specifications.
654 while (fgets(line, sizeof(line), f)) {
655 /* Update line number counter. */
657 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
662 fatal("%s: terminating, %d bad configuration options",
663 filename, bad_options);
667 * Initializes options to special values that indicate that they have not yet
668 * been set. Read_config_file will only set options with this value. Options
669 * are processed in the following order: command line, user config file,
670 * system config file. Last, fill_default_options is called.
674 initialize_options(Options * options)
676 memset(options, 'X', sizeof(*options));
677 options->forward_agent = -1;
678 options->forward_x11 = -1;
679 options->xauth_location = NULL;
680 options->gateway_ports = -1;
681 options->use_privileged_port = -1;
682 options->rhosts_authentication = -1;
683 options->rsa_authentication = -1;
684 options->pubkey_authentication = -1;
685 options->challenge_reponse_authentication = -1;
687 options->kerberos_authentication = -1;
690 options->kerberos_tgt_passing = -1;
691 options->afs_token_passing = -1;
693 options->password_authentication = -1;
694 options->kbd_interactive_authentication = -1;
695 options->kbd_interactive_devices = NULL;
696 options->rhosts_rsa_authentication = -1;
697 options->fallback_to_rsh = -1;
698 options->use_rsh = -1;
699 options->batch_mode = -1;
700 options->check_host_ip = -1;
701 options->strict_host_key_checking = -1;
702 options->compression = -1;
703 options->keepalives = -1;
704 options->compression_level = -1;
706 options->connection_attempts = -1;
707 options->number_of_password_prompts = -1;
708 options->cipher = -1;
709 options->ciphers = NULL;
710 options->macs = NULL;
711 options->protocol = SSH_PROTO_UNKNOWN;
712 options->num_identity_files = 0;
713 options->hostname = NULL;
714 options->host_key_alias = NULL;
715 options->proxy_command = NULL;
716 options->user = NULL;
717 options->escape_char = -1;
718 options->system_hostfile = NULL;
719 options->user_hostfile = NULL;
720 options->system_hostfile2 = NULL;
721 options->user_hostfile2 = NULL;
722 options->num_local_forwards = 0;
723 options->num_remote_forwards = 0;
724 options->log_level = (LogLevel) - 1;
728 * Called after processing other sources of option data, this fills those
729 * options for which no value has been specified with their default values.
733 fill_default_options(Options * options)
737 if (options->forward_agent == -1)
738 options->forward_agent = 0;
739 if (options->forward_x11 == -1)
740 options->forward_x11 = 0;
742 if (options->xauth_location == NULL)
743 options->xauth_location = XAUTH_PATH;
744 #endif /* XAUTH_PATH */
745 if (options->gateway_ports == -1)
746 options->gateway_ports = 0;
747 if (options->use_privileged_port == -1)
748 options->use_privileged_port = 0;
749 if (options->rhosts_authentication == -1)
750 options->rhosts_authentication = 1;
751 if (options->rsa_authentication == -1)
752 options->rsa_authentication = 1;
753 if (options->pubkey_authentication == -1)
754 options->pubkey_authentication = 1;
755 if (options->challenge_reponse_authentication == -1)
756 options->challenge_reponse_authentication = 0;
758 if (options->kerberos_authentication == -1)
759 options->kerberos_authentication = 1;
762 if (options->kerberos_tgt_passing == -1)
763 options->kerberos_tgt_passing = 1;
764 if (options->afs_token_passing == -1)
765 options->afs_token_passing = 1;
767 if (options->password_authentication == -1)
768 options->password_authentication = 1;
769 if (options->kbd_interactive_authentication == -1)
770 options->kbd_interactive_authentication = 1;
771 if (options->rhosts_rsa_authentication == -1)
772 options->rhosts_rsa_authentication = 1;
773 if (options->fallback_to_rsh == -1)
774 options->fallback_to_rsh = 0;
775 if (options->use_rsh == -1)
776 options->use_rsh = 0;
777 if (options->batch_mode == -1)
778 options->batch_mode = 0;
779 if (options->check_host_ip == -1)
780 options->check_host_ip = 1;
781 if (options->strict_host_key_checking == -1)
782 options->strict_host_key_checking = 2; /* 2 is default */
783 if (options->compression == -1)
784 options->compression = 0;
785 if (options->keepalives == -1)
786 options->keepalives = 1;
787 if (options->compression_level == -1)
788 options->compression_level = 6;
789 if (options->port == -1)
790 options->port = 0; /* Filled in ssh_connect. */
791 if (options->connection_attempts == -1)
792 options->connection_attempts = 4;
793 if (options->number_of_password_prompts == -1)
794 options->number_of_password_prompts = 3;
795 /* Selected in ssh_login(). */
796 if (options->cipher == -1)
797 options->cipher = SSH_CIPHER_NOT_SET;
798 /* options->ciphers, default set in myproposals.h */
799 /* options->macs, default set in myproposals.h */
800 if (options->protocol == SSH_PROTO_UNKNOWN)
801 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
802 if (options->num_identity_files == 0) {
803 if (options->protocol & SSH_PROTO_1) {
804 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
805 options->identity_files[options->num_identity_files] =
807 snprintf(options->identity_files[options->num_identity_files++],
808 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
810 if (options->protocol & SSH_PROTO_2) {
811 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
812 options->identity_files[options->num_identity_files] =
814 snprintf(options->identity_files[options->num_identity_files++],
815 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
817 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 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_DSA);
824 if (options->escape_char == -1)
825 options->escape_char = '~';
826 if (options->system_hostfile == NULL)
827 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
828 if (options->user_hostfile == NULL)
829 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
830 if (options->system_hostfile2 == NULL)
831 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
832 if (options->user_hostfile2 == NULL)
833 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
834 if (options->log_level == (LogLevel) - 1)
835 options->log_level = SYSLOG_LEVEL_INFO;
836 /* options->proxy_command should not be set by default */
837 /* options->user will be set in the main program if appropriate */
838 /* options->hostname will be set in the main program if appropriate */
839 /* options->host_key_alias should not be set by default */