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.51 2000/12/19 23:17:57 markus Exp $");
23 /* Format of the configuration file:
25 # Configuration data is parsed as follows:
26 # 1. command line options
27 # 2. user-specific file
29 # Any configuration value is only changed the first time it is set.
30 # Thus, host-specific definitions should be at the beginning of the
31 # configuration file, and defaults at the end.
33 # Host-specific declarations. These may override anything above. A single
34 # host may match multiple declarations; these are processed in the order
35 # that they are given in.
41 HostName another.host.name.real.org
48 RemoteForward 9999 shadows.cs.hut.fi:9999
54 RhostsAuthentication no
55 PasswordAuthentication no
59 ProxyCommand ssh-proxy %h %p
66 PasswordAuthentication no
68 # Defaults for various options
72 RhostsAuthentication yes
73 PasswordAuthentication yes
75 RhostsRSAAuthentication yes
78 StrictHostKeyChecking yes
80 IdentityFile ~/.ssh/identity
90 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
91 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
92 oSkeyAuthentication, oXAuthLocation,
94 oKerberosAuthentication,
97 oKerberosTgtPassing, oAFSTokenPassing,
99 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
100 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
101 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
102 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
103 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
104 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol,
105 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
106 oKbdInteractiveAuthentication, oKbdInteractiveDevices
109 /* Textual representations of the tokens. */
115 { "forwardagent", oForwardAgent },
116 { "forwardx11", oForwardX11 },
117 { "xauthlocation", oXAuthLocation },
118 { "gatewayports", oGatewayPorts },
119 { "useprivilegedport", oUsePrivilegedPort },
120 { "rhostsauthentication", oRhostsAuthentication },
121 { "passwordauthentication", oPasswordAuthentication },
122 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
123 { "kbdinteractivedevices", oKbdInteractiveDevices },
124 { "rsaauthentication", oRSAAuthentication },
125 { "pubkeyauthentication", oPubkeyAuthentication },
126 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
127 { "skeyauthentication", oSkeyAuthentication },
129 { "kerberosauthentication", oKerberosAuthentication },
132 { "kerberostgtpassing", oKerberosTgtPassing },
133 { "afstokenpassing", oAFSTokenPassing },
135 { "fallbacktorsh", oFallBackToRsh },
136 { "usersh", oUseRsh },
137 { "identityfile", oIdentityFile },
138 { "identityfile2", oIdentityFile }, /* alias */
139 { "hostname", oHostName },
140 { "proxycommand", oProxyCommand },
142 { "cipher", oCipher },
143 { "ciphers", oCiphers },
144 { "protocol", oProtocol },
145 { "remoteforward", oRemoteForward },
146 { "localforward", oLocalForward },
149 { "escapechar", oEscapeChar },
150 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
151 { "globalknownhostsfile", oGlobalKnownHostsFile },
152 { "userknownhostsfile", oUserKnownHostsFile },
153 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
154 { "userknownhostsfile2", oUserKnownHostsFile2 },
155 { "connectionattempts", oConnectionAttempts },
156 { "batchmode", oBatchMode },
157 { "checkhostip", oCheckHostIP },
158 { "stricthostkeychecking", oStrictHostKeyChecking },
159 { "compression", oCompression },
160 { "compressionlevel", oCompressionLevel },
161 { "keepalive", oKeepAlives },
162 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
163 { "tisauthentication", oTISAuthentication },
164 { "loglevel", oLogLevel },
169 * Adds a local TCP/IP port forward to options. Never returns if there is an
174 add_local_forward(Options *options, u_short port, const char *host,
179 extern uid_t original_real_uid;
180 if (port < IPPORT_RESERVED && original_real_uid != 0)
181 fatal("Privileged ports can only be forwarded by root.\n");
183 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
184 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
185 fwd = &options->local_forwards[options->num_local_forwards++];
187 fwd->host = xstrdup(host);
188 fwd->host_port = host_port;
192 * Adds a remote TCP/IP port forward to options. Never returns if there is
197 add_remote_forward(Options *options, u_short port, const char *host,
201 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
202 fatal("Too many remote forwards (max %d).",
203 SSH_MAX_FORWARDS_PER_DIRECTION);
204 fwd = &options->remote_forwards[options->num_remote_forwards++];
206 fwd->host = xstrdup(host);
207 fwd->host_port = host_port;
211 * Returns the number of the token pointed to by cp of length len. Never
212 * returns if the token is not known.
216 parse_token(const char *cp, const char *filename, int linenum)
220 for (i = 0; keywords[i].name; i++)
221 if (strcasecmp(cp, keywords[i].name) == 0)
222 return keywords[i].opcode;
224 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
225 filename, linenum, cp);
230 * Processes a single option line as used in the configuration files. This
231 * only sets those values that have not already been set.
235 process_config_line(Options *options, const char *host,
236 char *line, const char *filename, int linenum,
239 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
240 int opcode, *intptr, value;
241 u_short fwd_port, fwd_host_port;
244 /* Get the keyword. (Each line is supposed to begin with a keyword). */
245 keyword = strdelim(&s);
246 /* Ignore leading whitespace. */
247 if (*keyword == '\0')
248 keyword = strdelim(&s);
249 if (!*keyword || *keyword == '\n' || *keyword == '#')
252 opcode = parse_token(keyword, filename, linenum);
256 /* don't panic, but count bad options */
260 intptr = &options->forward_agent;
263 if (!arg || *arg == '\0')
264 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
265 value = 0; /* To avoid compiler warning... */
266 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
268 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
271 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
272 if (*activep && *intptr == -1)
277 intptr = &options->forward_x11;
281 intptr = &options->gateway_ports;
284 case oUsePrivilegedPort:
285 intptr = &options->use_privileged_port;
288 case oRhostsAuthentication:
289 intptr = &options->rhosts_authentication;
292 case oPasswordAuthentication:
293 intptr = &options->password_authentication;
296 case oKbdInteractiveAuthentication:
297 intptr = &options->kbd_interactive_authentication;
300 case oKbdInteractiveDevices:
301 charptr = &options->kbd_interactive_devices;
304 case oPubkeyAuthentication:
305 intptr = &options->pubkey_authentication;
308 case oRSAAuthentication:
309 intptr = &options->rsa_authentication;
312 case oRhostsRSAAuthentication:
313 intptr = &options->rhosts_rsa_authentication;
316 case oTISAuthentication:
317 /* fallthrough, there is no difference on the client side */
318 case oSkeyAuthentication:
319 intptr = &options->skey_authentication;
323 case oKerberosAuthentication:
324 intptr = &options->kerberos_authentication;
329 case oKerberosTgtPassing:
330 intptr = &options->kerberos_tgt_passing;
333 case oAFSTokenPassing:
334 intptr = &options->afs_token_passing;
339 intptr = &options->fallback_to_rsh;
343 intptr = &options->use_rsh;
347 intptr = &options->batch_mode;
351 intptr = &options->check_host_ip;
354 case oStrictHostKeyChecking:
355 intptr = &options->strict_host_key_checking;
357 if (!arg || *arg == '\0')
358 fatal("%.200s line %d: Missing yes/no argument.",
360 value = 0; /* To avoid compiler warning... */
361 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
363 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
365 else if (strcmp(arg, "ask") == 0)
368 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
369 if (*activep && *intptr == -1)
374 intptr = &options->compression;
378 intptr = &options->keepalives;
381 case oNumberOfPasswordPrompts:
382 intptr = &options->number_of_password_prompts;
385 case oCompressionLevel:
386 intptr = &options->compression_level;
391 if (!arg || *arg == '\0')
392 fatal("%.200s line %d: Missing argument.", filename, linenum);
394 intptr = &options->num_identity_files;
395 if (*intptr >= SSH_MAX_IDENTITY_FILES)
396 fatal("%.200s line %d: Too many identity files specified (max %d).",
397 filename, linenum, SSH_MAX_IDENTITY_FILES);
398 charptr = &options->identity_files[*intptr];
399 *charptr = xstrdup(arg);
400 *intptr = *intptr + 1;
405 charptr=&options->xauth_location;
409 charptr = &options->user;
412 if (!arg || *arg == '\0')
413 fatal("%.200s line %d: Missing argument.", filename, linenum);
414 if (*activep && *charptr == NULL)
415 *charptr = xstrdup(arg);
418 case oGlobalKnownHostsFile:
419 charptr = &options->system_hostfile;
422 case oUserKnownHostsFile:
423 charptr = &options->user_hostfile;
426 case oGlobalKnownHostsFile2:
427 charptr = &options->system_hostfile2;
430 case oUserKnownHostsFile2:
431 charptr = &options->user_hostfile2;
435 charptr = &options->hostname;
439 charptr = &options->proxy_command;
440 string = xstrdup("");
441 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
442 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
446 if (*activep && *charptr == NULL)
453 intptr = &options->port;
456 if (!arg || *arg == '\0')
457 fatal("%.200s line %d: Missing argument.", filename, linenum);
458 if (arg[0] < '0' || arg[0] > '9')
459 fatal("%.200s line %d: Bad number.", filename, linenum);
461 /* Octal, decimal, or hex format? */
462 value = strtol(arg, &endofnumber, 0);
463 if (arg == endofnumber)
464 fatal("%.200s line %d: Bad number.", filename, linenum);
465 if (*activep && *intptr == -1)
469 case oConnectionAttempts:
470 intptr = &options->connection_attempts;
474 intptr = &options->cipher;
476 if (!arg || *arg == '\0')
477 fatal("%.200s line %d: Missing argument.", filename, linenum);
478 value = cipher_number(arg);
480 fatal("%.200s line %d: Bad cipher '%s'.",
481 filename, linenum, arg ? arg : "<NONE>");
482 if (*activep && *intptr == -1)
488 if (!arg || *arg == '\0')
489 fatal("%.200s line %d: Missing argument.", filename, linenum);
490 if (!ciphers_valid(arg))
491 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
492 filename, linenum, arg ? arg : "<NONE>");
493 if (*activep && options->ciphers == NULL)
494 options->ciphers = xstrdup(arg);
498 intptr = &options->protocol;
500 if (!arg || *arg == '\0')
501 fatal("%.200s line %d: Missing argument.", filename, linenum);
502 value = proto_spec(arg);
503 if (value == SSH_PROTO_UNKNOWN)
504 fatal("%.200s line %d: Bad protocol spec '%s'.",
505 filename, linenum, arg ? arg : "<NONE>");
506 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
511 intptr = (int *) &options->log_level;
513 value = log_level_number(arg);
514 if (value == (LogLevel) - 1)
515 fatal("%.200s line %d: unsupported log level '%s'\n",
516 filename, linenum, arg ? arg : "<NONE>");
517 if (*activep && (LogLevel) * intptr == -1)
518 *intptr = (LogLevel) value;
523 if (!arg || *arg == '\0')
524 fatal("%.200s line %d: Missing argument.", filename, linenum);
525 if (arg[0] < '0' || arg[0] > '9')
526 fatal("%.200s line %d: Badly formatted port number.",
528 fwd_port = atoi(arg);
530 if (!arg || *arg == '\0')
531 fatal("%.200s line %d: Missing second argument.",
533 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
534 fatal("%.200s line %d: Badly formatted host:port.",
537 add_remote_forward(options, fwd_port, buf, fwd_host_port);
542 if (!arg || *arg == '\0')
543 fatal("%.200s line %d: Missing argument.", filename, linenum);
544 if (arg[0] < '0' || arg[0] > '9')
545 fatal("%.200s line %d: Badly formatted port number.",
547 fwd_port = atoi(arg);
549 if (!arg || *arg == '\0')
550 fatal("%.200s line %d: Missing second argument.",
552 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
553 fatal("%.200s line %d: Badly formatted host:port.",
556 add_local_forward(options, fwd_port, buf, fwd_host_port);
561 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
562 if (match_pattern(host, arg)) {
563 debug("Applying options for %.100s", arg);
567 /* Avoid garbage check below, as strdelim is done. */
571 intptr = &options->escape_char;
573 if (!arg || *arg == '\0')
574 fatal("%.200s line %d: Missing argument.", filename, linenum);
575 if (arg[0] == '^' && arg[2] == 0 &&
576 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
577 value = (u_char) arg[1] & 31;
578 else if (strlen(arg) == 1)
579 value = (u_char) arg[0];
580 else if (strcmp(arg, "none") == 0)
583 fatal("%.200s line %d: Bad escape character.",
586 value = 0; /* Avoid compiler warning. */
588 if (*activep && *intptr == -1)
593 fatal("process_config_line: Unimplemented opcode %d", opcode);
596 /* Check that there is no garbage at end of line. */
597 if ((arg = strdelim(&s)) != NULL && *arg != '\0')
599 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
600 filename, linenum, arg);
607 * Reads the config file and modifies the options accordingly. Options
608 * should already be initialized before this call. This never returns if
609 * there is an error. If the file does not exist, this returns immediately.
613 read_config_file(const char *filename, const char *host, Options *options)
621 f = fopen(filename, "r");
625 debug("Reading configuration data %.200s", filename);
628 * Mark that we are now processing the options. This flag is turned
629 * on/off by Host specifications.
633 while (fgets(line, sizeof(line), f)) {
634 /* Update line number counter. */
636 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
641 fatal("%s: terminating, %d bad configuration options\n",
642 filename, bad_options);
646 * Initializes options to special values that indicate that they have not yet
647 * been set. Read_config_file will only set options with this value. Options
648 * are processed in the following order: command line, user config file,
649 * system config file. Last, fill_default_options is called.
653 initialize_options(Options * options)
655 memset(options, 'X', sizeof(*options));
656 options->forward_agent = -1;
657 options->forward_x11 = -1;
658 options->xauth_location = NULL;
659 options->gateway_ports = -1;
660 options->use_privileged_port = -1;
661 options->rhosts_authentication = -1;
662 options->rsa_authentication = -1;
663 options->pubkey_authentication = -1;
664 options->skey_authentication = -1;
666 options->kerberos_authentication = -1;
669 options->kerberos_tgt_passing = -1;
670 options->afs_token_passing = -1;
672 options->password_authentication = -1;
673 options->kbd_interactive_authentication = -1;
674 options->kbd_interactive_devices = NULL;
675 options->rhosts_rsa_authentication = -1;
676 options->fallback_to_rsh = -1;
677 options->use_rsh = -1;
678 options->batch_mode = -1;
679 options->check_host_ip = -1;
680 options->strict_host_key_checking = -1;
681 options->compression = -1;
682 options->keepalives = -1;
683 options->compression_level = -1;
685 options->connection_attempts = -1;
686 options->number_of_password_prompts = -1;
687 options->cipher = -1;
688 options->ciphers = NULL;
689 options->protocol = SSH_PROTO_UNKNOWN;
690 options->num_identity_files = 0;
691 options->hostname = NULL;
692 options->proxy_command = NULL;
693 options->user = NULL;
694 options->escape_char = -1;
695 options->system_hostfile = NULL;
696 options->user_hostfile = NULL;
697 options->system_hostfile2 = NULL;
698 options->user_hostfile2 = NULL;
699 options->num_local_forwards = 0;
700 options->num_remote_forwards = 0;
701 options->log_level = (LogLevel) - 1;
705 * Called after processing other sources of option data, this fills those
706 * options for which no value has been specified with their default values.
710 fill_default_options(Options * options)
712 if (options->forward_agent == -1)
713 options->forward_agent = 0;
714 if (options->forward_x11 == -1)
715 options->forward_x11 = 0;
717 if (options->xauth_location == NULL)
718 options->xauth_location = XAUTH_PATH;
719 #endif /* XAUTH_PATH */
720 if (options->gateway_ports == -1)
721 options->gateway_ports = 0;
722 if (options->use_privileged_port == -1)
723 options->use_privileged_port = 1;
724 if (options->rhosts_authentication == -1)
725 options->rhosts_authentication = 1;
726 if (options->rsa_authentication == -1)
727 options->rsa_authentication = 1;
728 if (options->pubkey_authentication == -1)
729 options->pubkey_authentication = 1;
730 if (options->skey_authentication == -1)
731 options->skey_authentication = 0;
733 if (options->kerberos_authentication == -1)
734 options->kerberos_authentication = 1;
737 if (options->kerberos_tgt_passing == -1)
738 options->kerberos_tgt_passing = 1;
739 if (options->afs_token_passing == -1)
740 options->afs_token_passing = 1;
742 if (options->password_authentication == -1)
743 options->password_authentication = 1;
744 if (options->kbd_interactive_authentication == -1)
745 options->kbd_interactive_authentication = 0;
746 if (options->rhosts_rsa_authentication == -1)
747 options->rhosts_rsa_authentication = 1;
748 if (options->fallback_to_rsh == -1)
749 options->fallback_to_rsh = 0;
750 if (options->use_rsh == -1)
751 options->use_rsh = 0;
752 if (options->batch_mode == -1)
753 options->batch_mode = 0;
754 if (options->check_host_ip == -1)
755 options->check_host_ip = 1;
756 if (options->strict_host_key_checking == -1)
757 options->strict_host_key_checking = 2; /* 2 is default */
758 if (options->compression == -1)
759 options->compression = 0;
760 if (options->keepalives == -1)
761 options->keepalives = 1;
762 if (options->compression_level == -1)
763 options->compression_level = 6;
764 if (options->port == -1)
765 options->port = 0; /* Filled in ssh_connect. */
766 if (options->connection_attempts == -1)
767 options->connection_attempts = 4;
768 if (options->number_of_password_prompts == -1)
769 options->number_of_password_prompts = 3;
770 /* Selected in ssh_login(). */
771 if (options->cipher == -1)
772 options->cipher = SSH_CIPHER_NOT_SET;
773 /* options->ciphers, default set in myproposals.h */
774 if (options->protocol == SSH_PROTO_UNKNOWN)
775 options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED;
776 if (options->num_identity_files == 0) {
777 if (options->protocol & SSH_PROTO_1) {
778 options->identity_files[options->num_identity_files] =
779 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
780 sprintf(options->identity_files[options->num_identity_files++],
781 "~/%.100s", SSH_CLIENT_IDENTITY);
783 if (options->protocol & SSH_PROTO_2) {
784 options->identity_files[options->num_identity_files] =
785 xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1);
786 sprintf(options->identity_files[options->num_identity_files++],
787 "~/%.100s", SSH_CLIENT_ID_DSA);
790 if (options->escape_char == -1)
791 options->escape_char = '~';
792 if (options->system_hostfile == NULL)
793 options->system_hostfile = SSH_SYSTEM_HOSTFILE;
794 if (options->user_hostfile == NULL)
795 options->user_hostfile = SSH_USER_HOSTFILE;
796 if (options->system_hostfile2 == NULL)
797 options->system_hostfile2 = SSH_SYSTEM_HOSTFILE2;
798 if (options->user_hostfile2 == NULL)
799 options->user_hostfile2 = SSH_USER_HOSTFILE2;
800 if (options->log_level == (LogLevel) - 1)
801 options->log_level = SYSLOG_LEVEL_INFO;
802 /* options->proxy_command should not be set by default */
803 /* options->user will be set in the main program if appropriate */
804 /* options->hostname will be set in the main program if appropriate */