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.52 2000/12/27 12:30:19 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, oHostKeyAlias
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 { "hostkeyalias", oHostKeyAlias },
141 { "proxycommand", oProxyCommand },
143 { "cipher", oCipher },
144 { "ciphers", oCiphers },
145 { "protocol", oProtocol },
146 { "remoteforward", oRemoteForward },
147 { "localforward", oLocalForward },
150 { "escapechar", oEscapeChar },
151 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
152 { "globalknownhostsfile", oGlobalKnownHostsFile },
153 { "userknownhostsfile", oUserKnownHostsFile },
154 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
155 { "userknownhostsfile2", oUserKnownHostsFile2 },
156 { "connectionattempts", oConnectionAttempts },
157 { "batchmode", oBatchMode },
158 { "checkhostip", oCheckHostIP },
159 { "stricthostkeychecking", oStrictHostKeyChecking },
160 { "compression", oCompression },
161 { "compressionlevel", oCompressionLevel },
162 { "keepalive", oKeepAlives },
163 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
164 { "tisauthentication", oTISAuthentication },
165 { "loglevel", oLogLevel },
170 * Adds a local TCP/IP port forward to options. Never returns if there is an
175 add_local_forward(Options *options, u_short port, const char *host,
180 extern uid_t original_real_uid;
181 if (port < IPPORT_RESERVED && original_real_uid != 0)
182 fatal("Privileged ports can only be forwarded by root.\n");
184 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
185 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
186 fwd = &options->local_forwards[options->num_local_forwards++];
188 fwd->host = xstrdup(host);
189 fwd->host_port = host_port;
193 * Adds a remote TCP/IP port forward to options. Never returns if there is
198 add_remote_forward(Options *options, u_short port, const char *host,
202 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
203 fatal("Too many remote forwards (max %d).",
204 SSH_MAX_FORWARDS_PER_DIRECTION);
205 fwd = &options->remote_forwards[options->num_remote_forwards++];
207 fwd->host = xstrdup(host);
208 fwd->host_port = host_port;
212 * Returns the number of the token pointed to by cp of length len. Never
213 * returns if the token is not known.
217 parse_token(const char *cp, const char *filename, int linenum)
221 for (i = 0; keywords[i].name; i++)
222 if (strcasecmp(cp, keywords[i].name) == 0)
223 return keywords[i].opcode;
225 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
226 filename, linenum, cp);
231 * Processes a single option line as used in the configuration files. This
232 * only sets those values that have not already been set.
236 process_config_line(Options *options, const char *host,
237 char *line, const char *filename, int linenum,
240 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
241 int opcode, *intptr, value;
242 u_short fwd_port, fwd_host_port;
245 /* Get the keyword. (Each line is supposed to begin with a keyword). */
246 keyword = strdelim(&s);
247 /* Ignore leading whitespace. */
248 if (*keyword == '\0')
249 keyword = strdelim(&s);
250 if (!*keyword || *keyword == '\n' || *keyword == '#')
253 opcode = parse_token(keyword, filename, linenum);
257 /* don't panic, but count bad options */
261 intptr = &options->forward_agent;
264 if (!arg || *arg == '\0')
265 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
266 value = 0; /* To avoid compiler warning... */
267 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
269 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
272 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
273 if (*activep && *intptr == -1)
278 intptr = &options->forward_x11;
282 intptr = &options->gateway_ports;
285 case oUsePrivilegedPort:
286 intptr = &options->use_privileged_port;
289 case oRhostsAuthentication:
290 intptr = &options->rhosts_authentication;
293 case oPasswordAuthentication:
294 intptr = &options->password_authentication;
297 case oKbdInteractiveAuthentication:
298 intptr = &options->kbd_interactive_authentication;
301 case oKbdInteractiveDevices:
302 charptr = &options->kbd_interactive_devices;
305 case oPubkeyAuthentication:
306 intptr = &options->pubkey_authentication;
309 case oRSAAuthentication:
310 intptr = &options->rsa_authentication;
313 case oRhostsRSAAuthentication:
314 intptr = &options->rhosts_rsa_authentication;
317 case oTISAuthentication:
318 /* fallthrough, there is no difference on the client side */
319 case oSkeyAuthentication:
320 intptr = &options->skey_authentication;
324 case oKerberosAuthentication:
325 intptr = &options->kerberos_authentication;
330 case oKerberosTgtPassing:
331 intptr = &options->kerberos_tgt_passing;
334 case oAFSTokenPassing:
335 intptr = &options->afs_token_passing;
340 intptr = &options->fallback_to_rsh;
344 intptr = &options->use_rsh;
348 intptr = &options->batch_mode;
352 intptr = &options->check_host_ip;
355 case oStrictHostKeyChecking:
356 intptr = &options->strict_host_key_checking;
358 if (!arg || *arg == '\0')
359 fatal("%.200s line %d: Missing yes/no argument.",
361 value = 0; /* To avoid compiler warning... */
362 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
364 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
366 else if (strcmp(arg, "ask") == 0)
369 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
370 if (*activep && *intptr == -1)
375 intptr = &options->compression;
379 intptr = &options->keepalives;
382 case oNumberOfPasswordPrompts:
383 intptr = &options->number_of_password_prompts;
386 case oCompressionLevel:
387 intptr = &options->compression_level;
392 if (!arg || *arg == '\0')
393 fatal("%.200s line %d: Missing argument.", filename, linenum);
395 intptr = &options->num_identity_files;
396 if (*intptr >= SSH_MAX_IDENTITY_FILES)
397 fatal("%.200s line %d: Too many identity files specified (max %d).",
398 filename, linenum, SSH_MAX_IDENTITY_FILES);
399 charptr = &options->identity_files[*intptr];
400 *charptr = xstrdup(arg);
401 *intptr = *intptr + 1;
406 charptr=&options->xauth_location;
410 charptr = &options->user;
413 if (!arg || *arg == '\0')
414 fatal("%.200s line %d: Missing argument.", filename, linenum);
415 if (*activep && *charptr == NULL)
416 *charptr = xstrdup(arg);
419 case oGlobalKnownHostsFile:
420 charptr = &options->system_hostfile;
423 case oUserKnownHostsFile:
424 charptr = &options->user_hostfile;
427 case oGlobalKnownHostsFile2:
428 charptr = &options->system_hostfile2;
431 case oUserKnownHostsFile2:
432 charptr = &options->user_hostfile2;
436 charptr = &options->hostname;
440 charptr = &options->host_key_alias;
444 charptr = &options->proxy_command;
445 string = xstrdup("");
446 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
447 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
451 if (*activep && *charptr == NULL)
458 intptr = &options->port;
461 if (!arg || *arg == '\0')
462 fatal("%.200s line %d: Missing argument.", filename, linenum);
463 if (arg[0] < '0' || arg[0] > '9')
464 fatal("%.200s line %d: Bad number.", filename, linenum);
466 /* Octal, decimal, or hex format? */
467 value = strtol(arg, &endofnumber, 0);
468 if (arg == endofnumber)
469 fatal("%.200s line %d: Bad number.", filename, linenum);
470 if (*activep && *intptr == -1)
474 case oConnectionAttempts:
475 intptr = &options->connection_attempts;
479 intptr = &options->cipher;
481 if (!arg || *arg == '\0')
482 fatal("%.200s line %d: Missing argument.", filename, linenum);
483 value = cipher_number(arg);
485 fatal("%.200s line %d: Bad cipher '%s'.",
486 filename, linenum, arg ? arg : "<NONE>");
487 if (*activep && *intptr == -1)
493 if (!arg || *arg == '\0')
494 fatal("%.200s line %d: Missing argument.", filename, linenum);
495 if (!ciphers_valid(arg))
496 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
497 filename, linenum, arg ? arg : "<NONE>");
498 if (*activep && options->ciphers == NULL)
499 options->ciphers = xstrdup(arg);
503 intptr = &options->protocol;
505 if (!arg || *arg == '\0')
506 fatal("%.200s line %d: Missing argument.", filename, linenum);
507 value = proto_spec(arg);
508 if (value == SSH_PROTO_UNKNOWN)
509 fatal("%.200s line %d: Bad protocol spec '%s'.",
510 filename, linenum, arg ? arg : "<NONE>");
511 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
516 intptr = (int *) &options->log_level;
518 value = log_level_number(arg);
519 if (value == (LogLevel) - 1)
520 fatal("%.200s line %d: unsupported log level '%s'\n",
521 filename, linenum, arg ? arg : "<NONE>");
522 if (*activep && (LogLevel) * intptr == -1)
523 *intptr = (LogLevel) value;
528 if (!arg || *arg == '\0')
529 fatal("%.200s line %d: Missing argument.", filename, linenum);
530 if (arg[0] < '0' || arg[0] > '9')
531 fatal("%.200s line %d: Badly formatted port number.",
533 fwd_port = atoi(arg);
535 if (!arg || *arg == '\0')
536 fatal("%.200s line %d: Missing second argument.",
538 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
539 fatal("%.200s line %d: Badly formatted host:port.",
542 add_remote_forward(options, fwd_port, buf, fwd_host_port);
547 if (!arg || *arg == '\0')
548 fatal("%.200s line %d: Missing argument.", filename, linenum);
549 if (arg[0] < '0' || arg[0] > '9')
550 fatal("%.200s line %d: Badly formatted port number.",
552 fwd_port = atoi(arg);
554 if (!arg || *arg == '\0')
555 fatal("%.200s line %d: Missing second argument.",
557 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
558 fatal("%.200s line %d: Badly formatted host:port.",
561 add_local_forward(options, fwd_port, buf, fwd_host_port);
566 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
567 if (match_pattern(host, arg)) {
568 debug("Applying options for %.100s", arg);
572 /* Avoid garbage check below, as strdelim is done. */
576 intptr = &options->escape_char;
578 if (!arg || *arg == '\0')
579 fatal("%.200s line %d: Missing argument.", filename, linenum);
580 if (arg[0] == '^' && arg[2] == 0 &&
581 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
582 value = (u_char) arg[1] & 31;
583 else if (strlen(arg) == 1)
584 value = (u_char) arg[0];
585 else if (strcmp(arg, "none") == 0)
588 fatal("%.200s line %d: Bad escape character.",
591 value = 0; /* Avoid compiler warning. */
593 if (*activep && *intptr == -1)
598 fatal("process_config_line: Unimplemented opcode %d", opcode);
601 /* Check that there is no garbage at end of line. */
602 if ((arg = strdelim(&s)) != NULL && *arg != '\0')
604 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
605 filename, linenum, arg);
612 * Reads the config file and modifies the options accordingly. Options
613 * should already be initialized before this call. This never returns if
614 * there is an error. If the file does not exist, this returns immediately.
618 read_config_file(const char *filename, const char *host, Options *options)
626 f = fopen(filename, "r");
630 debug("Reading configuration data %.200s", filename);
633 * Mark that we are now processing the options. This flag is turned
634 * on/off by Host specifications.
638 while (fgets(line, sizeof(line), f)) {
639 /* Update line number counter. */
641 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
646 fatal("%s: terminating, %d bad configuration options\n",
647 filename, bad_options);
651 * Initializes options to special values that indicate that they have not yet
652 * been set. Read_config_file will only set options with this value. Options
653 * are processed in the following order: command line, user config file,
654 * system config file. Last, fill_default_options is called.
658 initialize_options(Options * options)
660 memset(options, 'X', sizeof(*options));
661 options->forward_agent = -1;
662 options->forward_x11 = -1;
663 options->xauth_location = NULL;
664 options->gateway_ports = -1;
665 options->use_privileged_port = -1;
666 options->rhosts_authentication = -1;
667 options->rsa_authentication = -1;
668 options->pubkey_authentication = -1;
669 options->skey_authentication = -1;
671 options->kerberos_authentication = -1;
674 options->kerberos_tgt_passing = -1;
675 options->afs_token_passing = -1;
677 options->password_authentication = -1;
678 options->kbd_interactive_authentication = -1;
679 options->kbd_interactive_devices = NULL;
680 options->rhosts_rsa_authentication = -1;
681 options->fallback_to_rsh = -1;
682 options->use_rsh = -1;
683 options->batch_mode = -1;
684 options->check_host_ip = -1;
685 options->strict_host_key_checking = -1;
686 options->compression = -1;
687 options->keepalives = -1;
688 options->compression_level = -1;
690 options->connection_attempts = -1;
691 options->number_of_password_prompts = -1;
692 options->cipher = -1;
693 options->ciphers = NULL;
694 options->protocol = SSH_PROTO_UNKNOWN;
695 options->num_identity_files = 0;
696 options->hostname = NULL;
697 options->host_key_alias = NULL;
698 options->proxy_command = NULL;
699 options->user = NULL;
700 options->escape_char = -1;
701 options->system_hostfile = NULL;
702 options->user_hostfile = NULL;
703 options->system_hostfile2 = NULL;
704 options->user_hostfile2 = NULL;
705 options->num_local_forwards = 0;
706 options->num_remote_forwards = 0;
707 options->log_level = (LogLevel) - 1;
711 * Called after processing other sources of option data, this fills those
712 * options for which no value has been specified with their default values.
716 fill_default_options(Options * options)
718 if (options->forward_agent == -1)
719 options->forward_agent = 0;
720 if (options->forward_x11 == -1)
721 options->forward_x11 = 0;
723 if (options->xauth_location == NULL)
724 options->xauth_location = XAUTH_PATH;
725 #endif /* XAUTH_PATH */
726 if (options->gateway_ports == -1)
727 options->gateway_ports = 0;
728 if (options->use_privileged_port == -1)
729 options->use_privileged_port = 1;
730 if (options->rhosts_authentication == -1)
731 options->rhosts_authentication = 1;
732 if (options->rsa_authentication == -1)
733 options->rsa_authentication = 1;
734 if (options->pubkey_authentication == -1)
735 options->pubkey_authentication = 1;
736 if (options->skey_authentication == -1)
737 options->skey_authentication = 0;
739 if (options->kerberos_authentication == -1)
740 options->kerberos_authentication = 1;
743 if (options->kerberos_tgt_passing == -1)
744 options->kerberos_tgt_passing = 1;
745 if (options->afs_token_passing == -1)
746 options->afs_token_passing = 1;
748 if (options->password_authentication == -1)
749 options->password_authentication = 1;
750 if (options->kbd_interactive_authentication == -1)
751 options->kbd_interactive_authentication = 0;
752 if (options->rhosts_rsa_authentication == -1)
753 options->rhosts_rsa_authentication = 1;
754 if (options->fallback_to_rsh == -1)
755 options->fallback_to_rsh = 0;
756 if (options->use_rsh == -1)
757 options->use_rsh = 0;
758 if (options->batch_mode == -1)
759 options->batch_mode = 0;
760 if (options->check_host_ip == -1)
761 options->check_host_ip = 1;
762 if (options->strict_host_key_checking == -1)
763 options->strict_host_key_checking = 2; /* 2 is default */
764 if (options->compression == -1)
765 options->compression = 0;
766 if (options->keepalives == -1)
767 options->keepalives = 1;
768 if (options->compression_level == -1)
769 options->compression_level = 6;
770 if (options->port == -1)
771 options->port = 0; /* Filled in ssh_connect. */
772 if (options->connection_attempts == -1)
773 options->connection_attempts = 4;
774 if (options->number_of_password_prompts == -1)
775 options->number_of_password_prompts = 3;
776 /* Selected in ssh_login(). */
777 if (options->cipher == -1)
778 options->cipher = SSH_CIPHER_NOT_SET;
779 /* options->ciphers, default set in myproposals.h */
780 if (options->protocol == SSH_PROTO_UNKNOWN)
781 options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED;
782 if (options->num_identity_files == 0) {
783 if (options->protocol & SSH_PROTO_1) {
784 options->identity_files[options->num_identity_files] =
785 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
786 sprintf(options->identity_files[options->num_identity_files++],
787 "~/%.100s", SSH_CLIENT_IDENTITY);
789 if (options->protocol & SSH_PROTO_2) {
790 options->identity_files[options->num_identity_files] =
791 xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1);
792 sprintf(options->identity_files[options->num_identity_files++],
793 "~/%.100s", SSH_CLIENT_ID_DSA);
796 if (options->escape_char == -1)
797 options->escape_char = '~';
798 if (options->system_hostfile == NULL)
799 options->system_hostfile = SSH_SYSTEM_HOSTFILE;
800 if (options->user_hostfile == NULL)
801 options->user_hostfile = SSH_USER_HOSTFILE;
802 if (options->system_hostfile2 == NULL)
803 options->system_hostfile2 = SSH_SYSTEM_HOSTFILE2;
804 if (options->user_hostfile2 == NULL)
805 options->user_hostfile2 = SSH_USER_HOSTFILE2;
806 if (options->log_level == (LogLevel) - 1)
807 options->log_level = SYSLOG_LEVEL_INFO;
808 /* options->proxy_command should not be set by default */
809 /* options->user will be set in the main program if appropriate */
810 /* options->hostname will be set in the main program if appropriate */
811 /* options->host_key_alias should not be set by default */