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.49 2000/10/11 20:27:23 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, oIdentityFile2,
105 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication,
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 { "dsaauthentication", oDSAAuthentication },
126 { "skeyauthentication", oSkeyAuthentication },
128 { "kerberosauthentication", oKerberosAuthentication },
131 { "kerberostgtpassing", oKerberosTgtPassing },
132 { "afstokenpassing", oAFSTokenPassing },
134 { "fallbacktorsh", oFallBackToRsh },
135 { "usersh", oUseRsh },
136 { "identityfile", oIdentityFile },
137 { "identityfile2", oIdentityFile2 },
138 { "hostname", oHostName },
139 { "proxycommand", oProxyCommand },
141 { "cipher", oCipher },
142 { "ciphers", oCiphers },
143 { "protocol", oProtocol },
144 { "remoteforward", oRemoteForward },
145 { "localforward", oLocalForward },
148 { "escapechar", oEscapeChar },
149 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
150 { "globalknownhostsfile", oGlobalKnownHostsFile },
151 { "userknownhostsfile", oUserKnownHostsFile },
152 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
153 { "userknownhostsfile2", oUserKnownHostsFile2 },
154 { "connectionattempts", oConnectionAttempts },
155 { "batchmode", oBatchMode },
156 { "checkhostip", oCheckHostIP },
157 { "stricthostkeychecking", oStrictHostKeyChecking },
158 { "compression", oCompression },
159 { "compressionlevel", oCompressionLevel },
160 { "keepalive", oKeepAlives },
161 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
162 { "tisauthentication", oTISAuthentication },
163 { "loglevel", oLogLevel },
168 * Adds a local TCP/IP port forward to options. Never returns if there is an
173 add_local_forward(Options *options, u_short port, const char *host,
178 extern uid_t original_real_uid;
179 if (port < IPPORT_RESERVED && original_real_uid != 0)
180 fatal("Privileged ports can only be forwarded by root.\n");
182 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
183 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
184 fwd = &options->local_forwards[options->num_local_forwards++];
186 fwd->host = xstrdup(host);
187 fwd->host_port = host_port;
191 * Adds a remote TCP/IP port forward to options. Never returns if there is
196 add_remote_forward(Options *options, u_short port, const char *host,
200 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
201 fatal("Too many remote forwards (max %d).",
202 SSH_MAX_FORWARDS_PER_DIRECTION);
203 fwd = &options->remote_forwards[options->num_remote_forwards++];
205 fwd->host = xstrdup(host);
206 fwd->host_port = host_port;
210 * Returns the number of the token pointed to by cp of length len. Never
211 * returns if the token is not known.
215 parse_token(const char *cp, const char *filename, int linenum)
219 for (i = 0; keywords[i].name; i++)
220 if (strcasecmp(cp, keywords[i].name) == 0)
221 return keywords[i].opcode;
223 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
224 filename, linenum, cp);
229 * Processes a single option line as used in the configuration files. This
230 * only sets those values that have not already been set.
234 process_config_line(Options *options, const char *host,
235 char *line, const char *filename, int linenum,
238 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
239 int opcode, *intptr, value;
240 u_short fwd_port, fwd_host_port;
243 /* Get the keyword. (Each line is supposed to begin with a keyword). */
244 keyword = strdelim(&s);
245 /* Ignore leading whitespace. */
246 if (*keyword == '\0')
247 keyword = strdelim(&s);
248 if (!*keyword || *keyword == '\n' || *keyword == '#')
251 opcode = parse_token(keyword, filename, linenum);
255 /* don't panic, but count bad options */
259 intptr = &options->forward_agent;
262 if (!arg || *arg == '\0')
263 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
264 value = 0; /* To avoid compiler warning... */
265 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
267 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
270 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
271 if (*activep && *intptr == -1)
276 intptr = &options->forward_x11;
280 intptr = &options->gateway_ports;
283 case oUsePrivilegedPort:
284 intptr = &options->use_privileged_port;
287 case oRhostsAuthentication:
288 intptr = &options->rhosts_authentication;
291 case oPasswordAuthentication:
292 intptr = &options->password_authentication;
295 case oKbdInteractiveAuthentication:
296 intptr = &options->kbd_interactive_authentication;
299 case oKbdInteractiveDevices:
300 charptr = &options->kbd_interactive_devices;
303 case oDSAAuthentication:
304 intptr = &options->dsa_authentication;
307 case oRSAAuthentication:
308 intptr = &options->rsa_authentication;
311 case oRhostsRSAAuthentication:
312 intptr = &options->rhosts_rsa_authentication;
315 case oTISAuthentication:
316 /* fallthrough, there is no difference on the client side */
317 case oSkeyAuthentication:
318 intptr = &options->skey_authentication;
322 case oKerberosAuthentication:
323 intptr = &options->kerberos_authentication;
328 case oKerberosTgtPassing:
329 intptr = &options->kerberos_tgt_passing;
332 case oAFSTokenPassing:
333 intptr = &options->afs_token_passing;
338 intptr = &options->fallback_to_rsh;
342 intptr = &options->use_rsh;
346 intptr = &options->batch_mode;
350 intptr = &options->check_host_ip;
353 case oStrictHostKeyChecking:
354 intptr = &options->strict_host_key_checking;
356 if (!arg || *arg == '\0')
357 fatal("%.200s line %d: Missing yes/no argument.",
359 value = 0; /* To avoid compiler warning... */
360 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
362 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
364 else if (strcmp(arg, "ask") == 0)
367 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
368 if (*activep && *intptr == -1)
373 intptr = &options->compression;
377 intptr = &options->keepalives;
380 case oNumberOfPasswordPrompts:
381 intptr = &options->number_of_password_prompts;
384 case oCompressionLevel:
385 intptr = &options->compression_level;
391 if (!arg || *arg == '\0')
392 fatal("%.200s line %d: Missing argument.", filename, linenum);
394 intptr = (opcode == oIdentityFile) ?
395 &options->num_identity_files :
396 &options->num_identity_files2;
397 if (*intptr >= SSH_MAX_IDENTITY_FILES)
398 fatal("%.200s line %d: Too many identity files specified (max %d).",
399 filename, linenum, SSH_MAX_IDENTITY_FILES);
400 charptr = (opcode == oIdentityFile) ?
401 &options->identity_files[*intptr] :
402 &options->identity_files2[*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->proxy_command;
444 string = xstrdup("");
445 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
446 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
450 if (*activep && *charptr == NULL)
457 intptr = &options->port;
460 if (!arg || *arg == '\0')
461 fatal("%.200s line %d: Missing argument.", filename, linenum);
462 if (arg[0] < '0' || arg[0] > '9')
463 fatal("%.200s line %d: Bad number.", filename, linenum);
465 /* Octal, decimal, or hex format? */
466 value = strtol(arg, &endofnumber, 0);
467 if (arg == endofnumber)
468 fatal("%.200s line %d: Bad number.", filename, linenum);
469 if (*activep && *intptr == -1)
473 case oConnectionAttempts:
474 intptr = &options->connection_attempts;
478 intptr = &options->cipher;
480 if (!arg || *arg == '\0')
481 fatal("%.200s line %d: Missing argument.", filename, linenum);
482 value = cipher_number(arg);
484 fatal("%.200s line %d: Bad cipher '%s'.",
485 filename, linenum, arg ? arg : "<NONE>");
486 if (*activep && *intptr == -1)
492 if (!arg || *arg == '\0')
493 fatal("%.200s line %d: Missing argument.", filename, linenum);
494 if (!ciphers_valid(arg))
495 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
496 filename, linenum, arg ? arg : "<NONE>");
497 if (*activep && options->ciphers == NULL)
498 options->ciphers = xstrdup(arg);
502 intptr = &options->protocol;
504 if (!arg || *arg == '\0')
505 fatal("%.200s line %d: Missing argument.", filename, linenum);
506 value = proto_spec(arg);
507 if (value == SSH_PROTO_UNKNOWN)
508 fatal("%.200s line %d: Bad protocol spec '%s'.",
509 filename, linenum, arg ? arg : "<NONE>");
510 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
515 intptr = (int *) &options->log_level;
517 value = log_level_number(arg);
518 if (value == (LogLevel) - 1)
519 fatal("%.200s line %d: unsupported log level '%s'\n",
520 filename, linenum, arg ? arg : "<NONE>");
521 if (*activep && (LogLevel) * intptr == -1)
522 *intptr = (LogLevel) value;
527 if (!arg || *arg == '\0')
528 fatal("%.200s line %d: Missing argument.", filename, linenum);
529 if (arg[0] < '0' || arg[0] > '9')
530 fatal("%.200s line %d: Badly formatted port number.",
532 fwd_port = atoi(arg);
534 if (!arg || *arg == '\0')
535 fatal("%.200s line %d: Missing second argument.",
537 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
538 fatal("%.200s line %d: Badly formatted host:port.",
541 add_remote_forward(options, fwd_port, buf, fwd_host_port);
546 if (!arg || *arg == '\0')
547 fatal("%.200s line %d: Missing argument.", filename, linenum);
548 if (arg[0] < '0' || arg[0] > '9')
549 fatal("%.200s line %d: Badly formatted port number.",
551 fwd_port = atoi(arg);
553 if (!arg || *arg == '\0')
554 fatal("%.200s line %d: Missing second argument.",
556 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
557 fatal("%.200s line %d: Badly formatted host:port.",
560 add_local_forward(options, fwd_port, buf, fwd_host_port);
565 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
566 if (match_pattern(host, arg)) {
567 debug("Applying options for %.100s", arg);
571 /* Avoid garbage check below, as strdelim is done. */
575 intptr = &options->escape_char;
577 if (!arg || *arg == '\0')
578 fatal("%.200s line %d: Missing argument.", filename, linenum);
579 if (arg[0] == '^' && arg[2] == 0 &&
580 (unsigned char) arg[1] >= 64 && (unsigned char) arg[1] < 128)
581 value = (unsigned char) arg[1] & 31;
582 else if (strlen(arg) == 1)
583 value = (unsigned char) arg[0];
584 else if (strcmp(arg, "none") == 0)
587 fatal("%.200s line %d: Bad escape character.",
590 value = 0; /* Avoid compiler warning. */
592 if (*activep && *intptr == -1)
597 fatal("process_config_line: Unimplemented opcode %d", opcode);
600 /* Check that there is no garbage at end of line. */
601 if ((arg = strdelim(&s)) != NULL && *arg != '\0')
603 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
604 filename, linenum, arg);
611 * Reads the config file and modifies the options accordingly. Options
612 * should already be initialized before this call. This never returns if
613 * there is an error. If the file does not exist, this returns immediately.
617 read_config_file(const char *filename, const char *host, Options *options)
625 f = fopen(filename, "r");
629 debug("Reading configuration data %.200s", filename);
632 * Mark that we are now processing the options. This flag is turned
633 * on/off by Host specifications.
637 while (fgets(line, sizeof(line), f)) {
638 /* Update line number counter. */
640 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
645 fatal("%s: terminating, %d bad configuration options\n",
646 filename, bad_options);
650 * Initializes options to special values that indicate that they have not yet
651 * been set. Read_config_file will only set options with this value. Options
652 * are processed in the following order: command line, user config file,
653 * system config file. Last, fill_default_options is called.
657 initialize_options(Options * options)
659 memset(options, 'X', sizeof(*options));
660 options->forward_agent = -1;
661 options->forward_x11 = -1;
662 options->xauth_location = NULL;
663 options->gateway_ports = -1;
664 options->use_privileged_port = -1;
665 options->rhosts_authentication = -1;
666 options->rsa_authentication = -1;
667 options->dsa_authentication = -1;
668 options->skey_authentication = -1;
670 options->kerberos_authentication = -1;
673 options->kerberos_tgt_passing = -1;
674 options->afs_token_passing = -1;
676 options->password_authentication = -1;
677 options->kbd_interactive_authentication = -1;
678 options->kbd_interactive_devices = NULL;
679 options->rhosts_rsa_authentication = -1;
680 options->fallback_to_rsh = -1;
681 options->use_rsh = -1;
682 options->batch_mode = -1;
683 options->check_host_ip = -1;
684 options->strict_host_key_checking = -1;
685 options->compression = -1;
686 options->keepalives = -1;
687 options->compression_level = -1;
689 options->connection_attempts = -1;
690 options->number_of_password_prompts = -1;
691 options->cipher = -1;
692 options->ciphers = NULL;
693 options->protocol = SSH_PROTO_UNKNOWN;
694 options->num_identity_files = 0;
695 options->num_identity_files2 = 0;
696 options->hostname = NULL;
697 options->proxy_command = NULL;
698 options->user = NULL;
699 options->escape_char = -1;
700 options->system_hostfile = NULL;
701 options->user_hostfile = NULL;
702 options->system_hostfile2 = NULL;
703 options->user_hostfile2 = NULL;
704 options->num_local_forwards = 0;
705 options->num_remote_forwards = 0;
706 options->log_level = (LogLevel) - 1;
710 * Called after processing other sources of option data, this fills those
711 * options for which no value has been specified with their default values.
715 fill_default_options(Options * options)
717 if (options->forward_agent == -1)
718 options->forward_agent = 0;
719 if (options->forward_x11 == -1)
720 options->forward_x11 = 0;
722 if (options->xauth_location == NULL)
723 options->xauth_location = XAUTH_PATH;
724 #endif /* XAUTH_PATH */
725 if (options->gateway_ports == -1)
726 options->gateway_ports = 0;
727 if (options->use_privileged_port == -1)
728 options->use_privileged_port = 1;
729 if (options->rhosts_authentication == -1)
730 options->rhosts_authentication = 1;
731 if (options->rsa_authentication == -1)
732 options->rsa_authentication = 1;
733 if (options->dsa_authentication == -1)
734 options->dsa_authentication = 1;
735 if (options->skey_authentication == -1)
736 options->skey_authentication = 0;
738 if (options->kerberos_authentication == -1)
739 options->kerberos_authentication = 1;
742 if (options->kerberos_tgt_passing == -1)
743 options->kerberos_tgt_passing = 1;
744 if (options->afs_token_passing == -1)
745 options->afs_token_passing = 1;
747 if (options->password_authentication == -1)
748 options->password_authentication = 1;
749 if (options->kbd_interactive_authentication == -1)
750 options->kbd_interactive_authentication = 0;
751 if (options->rhosts_rsa_authentication == -1)
752 options->rhosts_rsa_authentication = 1;
753 if (options->fallback_to_rsh == -1)
754 options->fallback_to_rsh = 0;
755 if (options->use_rsh == -1)
756 options->use_rsh = 0;
757 if (options->batch_mode == -1)
758 options->batch_mode = 0;
759 if (options->check_host_ip == -1)
760 options->check_host_ip = 1;
761 if (options->strict_host_key_checking == -1)
762 options->strict_host_key_checking = 2; /* 2 is default */
763 if (options->compression == -1)
764 options->compression = 0;
765 if (options->keepalives == -1)
766 options->keepalives = 1;
767 if (options->compression_level == -1)
768 options->compression_level = 6;
769 if (options->port == -1)
770 options->port = 0; /* Filled in ssh_connect. */
771 if (options->connection_attempts == -1)
772 options->connection_attempts = 4;
773 if (options->number_of_password_prompts == -1)
774 options->number_of_password_prompts = 3;
775 /* Selected in ssh_login(). */
776 if (options->cipher == -1)
777 options->cipher = SSH_CIPHER_NOT_SET;
778 /* options->ciphers, default set in myproposals.h */
779 if (options->protocol == SSH_PROTO_UNKNOWN)
780 options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED;
781 if (options->num_identity_files == 0) {
782 options->identity_files[0] =
783 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
784 sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
785 options->num_identity_files = 1;
787 if (options->num_identity_files2 == 0) {
788 options->identity_files2[0] =
789 xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1);
790 sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA);
791 options->num_identity_files2 = 1;
793 if (options->escape_char == -1)
794 options->escape_char = '~';
795 if (options->system_hostfile == NULL)
796 options->system_hostfile = SSH_SYSTEM_HOSTFILE;
797 if (options->user_hostfile == NULL)
798 options->user_hostfile = SSH_USER_HOSTFILE;
799 if (options->system_hostfile2 == NULL)
800 options->system_hostfile2 = SSH_SYSTEM_HOSTFILE2;
801 if (options->user_hostfile2 == NULL)
802 options->user_hostfile2 = SSH_USER_HOSTFILE2;
803 if (options->log_level == (LogLevel) - 1)
804 options->log_level = SYSLOG_LEVEL_INFO;
805 /* options->proxy_command should not be set by default */
806 /* options->user will be set in the main program if appropriate */
807 /* options->hostname will be set in the main program if appropriate */