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.61 2001/02/08 14:39:36 deraadt Exp $");
21 #include "pathnames.h"
27 /* Format of the configuration file:
29 # Configuration data is parsed as follows:
30 # 1. command line options
31 # 2. user-specific file
33 # Any configuration value is only changed the first time it is set.
34 # Thus, host-specific definitions should be at the beginning of the
35 # configuration file, and defaults at the end.
37 # Host-specific declarations. These may override anything above. A single
38 # host may match multiple declarations; these are processed in the order
39 # that they are given in.
45 HostName another.host.name.real.org
52 RemoteForward 9999 shadows.cs.hut.fi:9999
58 RhostsAuthentication no
59 PasswordAuthentication no
63 ProxyCommand ssh-proxy %h %p
70 PasswordAuthentication no
72 # Defaults for various options
76 RhostsAuthentication yes
77 PasswordAuthentication yes
79 RhostsRSAAuthentication yes
82 StrictHostKeyChecking yes
84 IdentityFile ~/.ssh/identity
94 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
95 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
96 oChallengeResponseAuthentication, oXAuthLocation,
98 oKerberosAuthentication,
101 oKerberosTgtPassing, oAFSTokenPassing,
103 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
104 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
105 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
106 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
107 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
108 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol,
109 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
110 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias
113 /* Textual representations of the tokens. */
119 { "forwardagent", oForwardAgent },
120 { "forwardx11", oForwardX11 },
121 { "xauthlocation", oXAuthLocation },
122 { "gatewayports", oGatewayPorts },
123 { "useprivilegedport", oUsePrivilegedPort },
124 { "rhostsauthentication", oRhostsAuthentication },
125 { "passwordauthentication", oPasswordAuthentication },
126 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
127 { "kbdinteractivedevices", oKbdInteractiveDevices },
128 { "rsaauthentication", oRSAAuthentication },
129 { "pubkeyauthentication", oPubkeyAuthentication },
130 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
131 { "challengeresponseauthentication", oChallengeResponseAuthentication },
132 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
133 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
135 { "kerberosauthentication", oKerberosAuthentication },
138 { "kerberostgtpassing", oKerberosTgtPassing },
139 { "afstokenpassing", oAFSTokenPassing },
141 { "fallbacktorsh", oFallBackToRsh },
142 { "usersh", oUseRsh },
143 { "identityfile", oIdentityFile },
144 { "identityfile2", oIdentityFile }, /* alias */
145 { "hostname", oHostName },
146 { "hostkeyalias", oHostKeyAlias },
147 { "proxycommand", oProxyCommand },
149 { "cipher", oCipher },
150 { "ciphers", oCiphers },
151 { "protocol", oProtocol },
152 { "remoteforward", oRemoteForward },
153 { "localforward", oLocalForward },
156 { "escapechar", oEscapeChar },
157 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
158 { "globalknownhostsfile", oGlobalKnownHostsFile },
159 { "userknownhostsfile", oUserKnownHostsFile },
160 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
161 { "userknownhostsfile2", oUserKnownHostsFile2 },
162 { "connectionattempts", oConnectionAttempts },
163 { "batchmode", oBatchMode },
164 { "checkhostip", oCheckHostIP },
165 { "stricthostkeychecking", oStrictHostKeyChecking },
166 { "compression", oCompression },
167 { "compressionlevel", oCompressionLevel },
168 { "keepalive", oKeepAlives },
169 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
170 { "loglevel", oLogLevel },
175 * Adds a local TCP/IP port forward to options. Never returns if there is an
180 add_local_forward(Options *options, u_short port, const char *host,
185 extern uid_t original_real_uid;
186 if (port < IPPORT_RESERVED && original_real_uid != 0)
187 fatal("Privileged ports can only be forwarded by root.\n");
189 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
190 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
191 fwd = &options->local_forwards[options->num_local_forwards++];
193 fwd->host = xstrdup(host);
194 fwd->host_port = host_port;
198 * Adds a remote TCP/IP port forward to options. Never returns if there is
203 add_remote_forward(Options *options, u_short port, const char *host,
207 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
208 fatal("Too many remote forwards (max %d).",
209 SSH_MAX_FORWARDS_PER_DIRECTION);
210 fwd = &options->remote_forwards[options->num_remote_forwards++];
212 fwd->host = xstrdup(host);
213 fwd->host_port = host_port;
217 * Returns the number of the token pointed to by cp of length len. Never
218 * returns if the token is not known.
222 parse_token(const char *cp, const char *filename, int linenum)
226 for (i = 0; keywords[i].name; i++)
227 if (strcasecmp(cp, keywords[i].name) == 0)
228 return keywords[i].opcode;
230 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
231 filename, linenum, cp);
236 * Processes a single option line as used in the configuration files. This
237 * only sets those values that have not already been set.
241 process_config_line(Options *options, const char *host,
242 char *line, const char *filename, int linenum,
245 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
246 int opcode, *intptr, value;
247 u_short fwd_port, fwd_host_port;
250 /* Get the keyword. (Each line is supposed to begin with a keyword). */
251 keyword = strdelim(&s);
252 /* Ignore leading whitespace. */
253 if (*keyword == '\0')
254 keyword = strdelim(&s);
255 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
258 opcode = parse_token(keyword, filename, linenum);
262 /* don't panic, but count bad options */
266 intptr = &options->forward_agent;
269 if (!arg || *arg == '\0')
270 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
271 value = 0; /* To avoid compiler warning... */
272 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
274 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
277 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
278 if (*activep && *intptr == -1)
283 intptr = &options->forward_x11;
287 intptr = &options->gateway_ports;
290 case oUsePrivilegedPort:
291 intptr = &options->use_privileged_port;
294 case oRhostsAuthentication:
295 intptr = &options->rhosts_authentication;
298 case oPasswordAuthentication:
299 intptr = &options->password_authentication;
302 case oKbdInteractiveAuthentication:
303 intptr = &options->kbd_interactive_authentication;
306 case oKbdInteractiveDevices:
307 charptr = &options->kbd_interactive_devices;
310 case oPubkeyAuthentication:
311 intptr = &options->pubkey_authentication;
314 case oRSAAuthentication:
315 intptr = &options->rsa_authentication;
318 case oRhostsRSAAuthentication:
319 intptr = &options->rhosts_rsa_authentication;
322 case oChallengeResponseAuthentication:
323 intptr = &options->challenge_reponse_authentication;
327 case oKerberosAuthentication:
328 intptr = &options->kerberos_authentication;
333 case oKerberosTgtPassing:
334 intptr = &options->kerberos_tgt_passing;
337 case oAFSTokenPassing:
338 intptr = &options->afs_token_passing;
343 intptr = &options->fallback_to_rsh;
347 intptr = &options->use_rsh;
351 intptr = &options->batch_mode;
355 intptr = &options->check_host_ip;
358 case oStrictHostKeyChecking:
359 intptr = &options->strict_host_key_checking;
361 if (!arg || *arg == '\0')
362 fatal("%.200s line %d: Missing yes/no/ask argument.",
364 value = 0; /* To avoid compiler warning... */
365 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
367 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
369 else if (strcmp(arg, "ask") == 0)
372 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
373 if (*activep && *intptr == -1)
378 intptr = &options->compression;
382 intptr = &options->keepalives;
385 case oNumberOfPasswordPrompts:
386 intptr = &options->number_of_password_prompts;
389 case oCompressionLevel:
390 intptr = &options->compression_level;
395 if (!arg || *arg == '\0')
396 fatal("%.200s line %d: Missing argument.", filename, linenum);
398 intptr = &options->num_identity_files;
399 if (*intptr >= SSH_MAX_IDENTITY_FILES)
400 fatal("%.200s line %d: Too many identity files specified (max %d).",
401 filename, linenum, SSH_MAX_IDENTITY_FILES);
402 charptr = &options->identity_files[*intptr];
403 *charptr = xstrdup(arg);
404 *intptr = *intptr + 1;
409 charptr=&options->xauth_location;
413 charptr = &options->user;
416 if (!arg || *arg == '\0')
417 fatal("%.200s line %d: Missing argument.", filename, linenum);
418 if (*activep && *charptr == NULL)
419 *charptr = xstrdup(arg);
422 case oGlobalKnownHostsFile:
423 charptr = &options->system_hostfile;
426 case oUserKnownHostsFile:
427 charptr = &options->user_hostfile;
430 case oGlobalKnownHostsFile2:
431 charptr = &options->system_hostfile2;
434 case oUserKnownHostsFile2:
435 charptr = &options->user_hostfile2;
439 charptr = &options->hostname;
443 charptr = &options->host_key_alias;
447 charptr = &options->proxy_command;
448 string = xstrdup("");
449 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
450 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
454 if (*activep && *charptr == NULL)
461 intptr = &options->port;
464 if (!arg || *arg == '\0')
465 fatal("%.200s line %d: Missing argument.", filename, linenum);
466 if (arg[0] < '0' || arg[0] > '9')
467 fatal("%.200s line %d: Bad number.", filename, linenum);
469 /* Octal, decimal, or hex format? */
470 value = strtol(arg, &endofnumber, 0);
471 if (arg == endofnumber)
472 fatal("%.200s line %d: Bad number.", filename, linenum);
473 if (*activep && *intptr == -1)
477 case oConnectionAttempts:
478 intptr = &options->connection_attempts;
482 intptr = &options->cipher;
484 if (!arg || *arg == '\0')
485 fatal("%.200s line %d: Missing argument.", filename, linenum);
486 value = cipher_number(arg);
488 fatal("%.200s line %d: Bad cipher '%s'.",
489 filename, linenum, arg ? arg : "<NONE>");
490 if (*activep && *intptr == -1)
496 if (!arg || *arg == '\0')
497 fatal("%.200s line %d: Missing argument.", filename, linenum);
498 if (!ciphers_valid(arg))
499 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
500 filename, linenum, arg ? arg : "<NONE>");
501 if (*activep && options->ciphers == NULL)
502 options->ciphers = xstrdup(arg);
506 intptr = &options->protocol;
508 if (!arg || *arg == '\0')
509 fatal("%.200s line %d: Missing argument.", filename, linenum);
510 value = proto_spec(arg);
511 if (value == SSH_PROTO_UNKNOWN)
512 fatal("%.200s line %d: Bad protocol spec '%s'.",
513 filename, linenum, arg ? arg : "<NONE>");
514 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
519 intptr = (int *) &options->log_level;
521 value = log_level_number(arg);
522 if (value == (LogLevel) - 1)
523 fatal("%.200s line %d: unsupported log level '%s'\n",
524 filename, linenum, arg ? arg : "<NONE>");
525 if (*activep && (LogLevel) * intptr == -1)
526 *intptr = (LogLevel) value;
531 if (!arg || *arg == '\0')
532 fatal("%.200s line %d: Missing argument.", filename, linenum);
533 if (arg[0] < '0' || arg[0] > '9')
534 fatal("%.200s line %d: Badly formatted port number.",
536 fwd_port = atoi(arg);
538 if (!arg || *arg == '\0')
539 fatal("%.200s line %d: Missing second argument.",
541 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
542 fatal("%.200s line %d: Badly formatted host:port.",
545 add_remote_forward(options, fwd_port, buf, fwd_host_port);
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_local_forward(options, fwd_port, buf, fwd_host_port);
569 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
570 if (match_pattern(host, arg)) {
571 debug("Applying options for %.100s", arg);
575 /* Avoid garbage check below, as strdelim is done. */
579 intptr = &options->escape_char;
581 if (!arg || *arg == '\0')
582 fatal("%.200s line %d: Missing argument.", filename, linenum);
583 if (arg[0] == '^' && arg[2] == 0 &&
584 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
585 value = (u_char) arg[1] & 31;
586 else if (strlen(arg) == 1)
587 value = (u_char) arg[0];
588 else if (strcmp(arg, "none") == 0)
591 fatal("%.200s line %d: Bad escape character.",
594 value = 0; /* Avoid compiler warning. */
596 if (*activep && *intptr == -1)
601 fatal("process_config_line: Unimplemented opcode %d", opcode);
604 /* Check that there is no garbage at end of line. */
605 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
606 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
607 filename, linenum, arg);
614 * Reads the config file and modifies the options accordingly. Options
615 * should already be initialized before this call. This never returns if
616 * there is an error. If the file does not exist, this returns immediately.
620 read_config_file(const char *filename, const char *host, Options *options)
628 f = fopen(filename, "r");
632 debug("Reading configuration data %.200s", filename);
635 * Mark that we are now processing the options. This flag is turned
636 * on/off by Host specifications.
640 while (fgets(line, sizeof(line), f)) {
641 /* Update line number counter. */
643 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
648 fatal("%s: terminating, %d bad configuration options\n",
649 filename, bad_options);
653 * Initializes options to special values that indicate that they have not yet
654 * been set. Read_config_file will only set options with this value. Options
655 * are processed in the following order: command line, user config file,
656 * system config file. Last, fill_default_options is called.
660 initialize_options(Options * options)
662 memset(options, 'X', sizeof(*options));
663 options->forward_agent = -1;
664 options->forward_x11 = -1;
665 options->xauth_location = NULL;
666 options->gateway_ports = -1;
667 options->use_privileged_port = -1;
668 options->rhosts_authentication = -1;
669 options->rsa_authentication = -1;
670 options->pubkey_authentication = -1;
671 options->challenge_reponse_authentication = -1;
673 options->kerberos_authentication = -1;
676 options->kerberos_tgt_passing = -1;
677 options->afs_token_passing = -1;
679 options->password_authentication = -1;
680 options->kbd_interactive_authentication = -1;
681 options->kbd_interactive_devices = NULL;
682 options->rhosts_rsa_authentication = -1;
683 options->fallback_to_rsh = -1;
684 options->use_rsh = -1;
685 options->batch_mode = -1;
686 options->check_host_ip = -1;
687 options->strict_host_key_checking = -1;
688 options->compression = -1;
689 options->keepalives = -1;
690 options->compression_level = -1;
692 options->connection_attempts = -1;
693 options->number_of_password_prompts = -1;
694 options->cipher = -1;
695 options->ciphers = NULL;
696 options->protocol = SSH_PROTO_UNKNOWN;
697 options->num_identity_files = 0;
698 options->hostname = NULL;
699 options->host_key_alias = NULL;
700 options->proxy_command = NULL;
701 options->user = NULL;
702 options->escape_char = -1;
703 options->system_hostfile = NULL;
704 options->user_hostfile = NULL;
705 options->system_hostfile2 = NULL;
706 options->user_hostfile2 = NULL;
707 options->num_local_forwards = 0;
708 options->num_remote_forwards = 0;
709 options->log_level = (LogLevel) - 1;
713 * Called after processing other sources of option data, this fills those
714 * options for which no value has been specified with their default values.
718 fill_default_options(Options * options)
722 if (options->forward_agent == -1)
723 options->forward_agent = 0;
724 if (options->forward_x11 == -1)
725 options->forward_x11 = 0;
727 if (options->xauth_location == NULL)
728 options->xauth_location = XAUTH_PATH;
729 #endif /* XAUTH_PATH */
730 if (options->gateway_ports == -1)
731 options->gateway_ports = 0;
732 if (options->use_privileged_port == -1)
733 options->use_privileged_port = 1;
734 if (options->rhosts_authentication == -1)
735 options->rhosts_authentication = 1;
736 if (options->rsa_authentication == -1)
737 options->rsa_authentication = 1;
738 if (options->pubkey_authentication == -1)
739 options->pubkey_authentication = 1;
740 if (options->challenge_reponse_authentication == -1)
741 options->challenge_reponse_authentication = 0;
743 if (options->kerberos_authentication == -1)
744 options->kerberos_authentication = 1;
747 if (options->kerberos_tgt_passing == -1)
748 options->kerberos_tgt_passing = 1;
749 if (options->afs_token_passing == -1)
750 options->afs_token_passing = 1;
752 if (options->password_authentication == -1)
753 options->password_authentication = 1;
754 if (options->kbd_interactive_authentication == -1)
755 options->kbd_interactive_authentication = 1;
756 if (options->rhosts_rsa_authentication == -1)
757 options->rhosts_rsa_authentication = 1;
758 if (options->fallback_to_rsh == -1)
759 options->fallback_to_rsh = 0;
760 if (options->use_rsh == -1)
761 options->use_rsh = 0;
762 if (options->batch_mode == -1)
763 options->batch_mode = 0;
764 if (options->check_host_ip == -1)
765 options->check_host_ip = 1;
766 if (options->strict_host_key_checking == -1)
767 options->strict_host_key_checking = 2; /* 2 is default */
768 if (options->compression == -1)
769 options->compression = 0;
770 if (options->keepalives == -1)
771 options->keepalives = 1;
772 if (options->compression_level == -1)
773 options->compression_level = 6;
774 if (options->port == -1)
775 options->port = 0; /* Filled in ssh_connect. */
776 if (options->connection_attempts == -1)
777 options->connection_attempts = 4;
778 if (options->number_of_password_prompts == -1)
779 options->number_of_password_prompts = 3;
780 /* Selected in ssh_login(). */
781 if (options->cipher == -1)
782 options->cipher = SSH_CIPHER_NOT_SET;
783 /* options->ciphers, default set in myproposals.h */
784 if (options->protocol == SSH_PROTO_UNKNOWN)
785 options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED;
786 if (options->num_identity_files == 0) {
787 if (options->protocol & SSH_PROTO_1) {
788 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
789 options->identity_files[options->num_identity_files] =
791 snprintf(options->identity_files[options->num_identity_files++],
792 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
794 if (options->protocol & SSH_PROTO_2) {
795 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
796 options->identity_files[options->num_identity_files] =
798 snprintf(options->identity_files[options->num_identity_files++],
799 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
802 if (options->escape_char == -1)
803 options->escape_char = '~';
804 if (options->system_hostfile == NULL)
805 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
806 if (options->user_hostfile == NULL)
807 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
808 if (options->system_hostfile2 == NULL)
809 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
810 if (options->user_hostfile2 == NULL)
811 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
812 if (options->log_level == (LogLevel) - 1)
813 options->log_level = SYSLOG_LEVEL_INFO;
814 /* options->proxy_command should not be set by default */
815 /* options->user will be set in the main program if appropriate */
816 /* options->hostname will be set in the main program if appropriate */
817 /* options->host_key_alias should not be set by default */