2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * As far as I am concerned, the code I have written for this software
6 * can be used freely for any purpose. Any derived versions of this
7 * software must be clearly marked as such, and if the derived work is
8 * incompatible with the protocol description in the RFC file, it must be
9 * called by a name other than "ssh" or "Secure Shell".
13 RCSID("$OpenBSD: servconf.c,v 1.77 2001/04/13 22:46:53 beck Exp $");
27 #include "pathnames.h"
28 #include "tildexpand.h"
34 void add_listen_addr(ServerOptions *options, char *addr, u_short port);
35 void add_one_listen_addr(ServerOptions *options, char *addr, u_short port);
37 /* AF_UNSPEC or AF_INET or AF_INET6 */
40 /* Initializes the server options to their default values. */
43 initialize_server_options(ServerOptions *options)
45 memset(options, 0, sizeof(*options));
46 options->num_ports = 0;
47 options->ports_from_cmdline = 0;
48 options->listen_addrs = NULL;
49 options->num_host_key_files = 0;
50 options->pid_file = NULL;
51 options->server_key_bits = -1;
52 options->login_grace_time = -1;
53 options->key_regeneration_time = -1;
54 options->permit_root_login = PERMIT_NOT_SET;
55 options->ignore_rhosts = -1;
56 options->ignore_user_known_hosts = -1;
57 options->print_motd = -1;
58 options->print_lastlog = -1;
59 options->check_mail = -1;
60 options->x11_forwarding = -1;
61 options->x11_display_offset = -1;
62 options->xauth_location = NULL;
63 options->strict_modes = -1;
64 options->keepalives = -1;
65 options->log_facility = (SyslogFacility) - 1;
66 options->log_level = (LogLevel) - 1;
67 options->rhosts_authentication = -1;
68 options->rhosts_rsa_authentication = -1;
69 options->hostbased_authentication = -1;
70 options->hostbased_uses_name_from_packet_only = -1;
71 options->rsa_authentication = -1;
72 options->pubkey_authentication = -1;
74 options->kerberos_authentication = -1;
75 options->kerberos_or_local_passwd = -1;
76 options->kerberos_ticket_cleanup = -1;
79 options->kerberos_tgt_passing = -1;
80 options->afs_token_passing = -1;
82 options->password_authentication = -1;
83 options->kbd_interactive_authentication = -1;
84 options->challenge_reponse_authentication = -1;
85 options->permit_empty_passwd = -1;
86 options->use_login = -1;
87 options->allow_tcp_forwarding = -1;
88 options->num_allow_users = 0;
89 options->num_deny_users = 0;
90 options->num_allow_groups = 0;
91 options->num_deny_groups = 0;
92 options->ciphers = NULL;
94 options->protocol = SSH_PROTO_UNKNOWN;
95 options->gateway_ports = -1;
96 options->num_subsystems = 0;
97 options->max_startups_begin = -1;
98 options->max_startups_rate = -1;
99 options->max_startups = -1;
100 options->banner = NULL;
101 options->reverse_mapping_check = -1;
102 options->client_alive_interval = -1;
103 options->client_alive_count_max = -1;
107 fill_default_server_options(ServerOptions *options)
109 if (options->protocol == SSH_PROTO_UNKNOWN)
110 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
111 if (options->num_host_key_files == 0) {
112 /* fill default hostkeys for protocols */
113 if (options->protocol & SSH_PROTO_1)
114 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE;
115 if (options->protocol & SSH_PROTO_2)
116 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE;
118 if (options->num_ports == 0)
119 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
120 if (options->listen_addrs == NULL)
121 add_listen_addr(options, NULL, 0);
122 if (options->pid_file == NULL)
123 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
124 if (options->server_key_bits == -1)
125 options->server_key_bits = 768;
126 if (options->login_grace_time == -1)
127 options->login_grace_time = 600;
128 if (options->key_regeneration_time == -1)
129 options->key_regeneration_time = 3600;
130 if (options->permit_root_login == PERMIT_NOT_SET)
131 options->permit_root_login = PERMIT_YES;
132 if (options->ignore_rhosts == -1)
133 options->ignore_rhosts = 1;
134 if (options->ignore_user_known_hosts == -1)
135 options->ignore_user_known_hosts = 0;
136 if (options->check_mail == -1)
137 options->check_mail = 0;
138 if (options->print_motd == -1)
139 options->print_motd = 1;
140 if (options->print_lastlog == -1)
141 options->print_lastlog = 1;
142 if (options->x11_forwarding == -1)
143 options->x11_forwarding = 0;
144 if (options->x11_display_offset == -1)
145 options->x11_display_offset = 10;
147 if (options->xauth_location == NULL)
148 options->xauth_location = XAUTH_PATH;
149 #endif /* XAUTH_PATH */
150 if (options->strict_modes == -1)
151 options->strict_modes = 1;
152 if (options->keepalives == -1)
153 options->keepalives = 1;
154 if (options->log_facility == (SyslogFacility) (-1))
155 options->log_facility = SYSLOG_FACILITY_AUTH;
156 if (options->log_level == (LogLevel) (-1))
157 options->log_level = SYSLOG_LEVEL_INFO;
158 if (options->rhosts_authentication == -1)
159 options->rhosts_authentication = 0;
160 if (options->rhosts_rsa_authentication == -1)
161 options->rhosts_rsa_authentication = 0;
162 if (options->hostbased_authentication == -1)
163 options->hostbased_authentication = 0;
164 if (options->hostbased_uses_name_from_packet_only == -1)
165 options->hostbased_uses_name_from_packet_only = 0;
166 if (options->rsa_authentication == -1)
167 options->rsa_authentication = 1;
168 if (options->pubkey_authentication == -1)
169 options->pubkey_authentication = 1;
171 if (options->kerberos_authentication == -1)
172 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
173 if (options->kerberos_or_local_passwd == -1)
174 options->kerberos_or_local_passwd = 1;
175 if (options->kerberos_ticket_cleanup == -1)
176 options->kerberos_ticket_cleanup = 1;
179 if (options->kerberos_tgt_passing == -1)
180 options->kerberos_tgt_passing = 0;
181 if (options->afs_token_passing == -1)
182 options->afs_token_passing = k_hasafs();
184 if (options->password_authentication == -1)
185 options->password_authentication = 1;
186 if (options->kbd_interactive_authentication == -1)
187 options->kbd_interactive_authentication = 0;
188 if (options->challenge_reponse_authentication == -1)
189 options->challenge_reponse_authentication = 1;
190 if (options->permit_empty_passwd == -1)
191 options->permit_empty_passwd = 0;
192 if (options->use_login == -1)
193 options->use_login = 0;
194 if (options->allow_tcp_forwarding == -1)
195 options->allow_tcp_forwarding = 1;
196 if (options->gateway_ports == -1)
197 options->gateway_ports = 0;
198 if (options->max_startups == -1)
199 options->max_startups = 10;
200 if (options->max_startups_rate == -1)
201 options->max_startups_rate = 100; /* 100% */
202 if (options->max_startups_begin == -1)
203 options->max_startups_begin = options->max_startups;
204 if (options->reverse_mapping_check == -1)
205 options->reverse_mapping_check = 0;
206 if (options->client_alive_interval == -1)
207 options->client_alive_interval = 0;
208 if (options->client_alive_count_max == -1)
209 options->client_alive_count_max = 3;
212 /* Keyword tokens. */
214 sBadOption, /* == unknown option */
215 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
216 sPermitRootLogin, sLogFacility, sLogLevel,
217 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
219 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
222 sKerberosTgtPassing, sAFSTokenPassing,
224 sChallengeResponseAuthentication,
225 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
226 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
227 sX11Forwarding, sX11DisplayOffset,
228 sStrictModes, sEmptyPasswd, sKeepAlives, sCheckMail,
229 sUseLogin, sAllowTcpForwarding,
230 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
231 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
232 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
233 sBanner, sReverseMappingCheck, sHostbasedAuthentication,
234 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
238 /* Textual representation of the tokens. */
241 ServerOpCodes opcode;
244 { "hostkey", sHostKeyFile },
245 { "hostdsakey", sHostKeyFile }, /* alias */
246 { "pidfile", sPidFile },
247 { "serverkeybits", sServerKeyBits },
248 { "logingracetime", sLoginGraceTime },
249 { "keyregenerationinterval", sKeyRegenerationTime },
250 { "permitrootlogin", sPermitRootLogin },
251 { "syslogfacility", sLogFacility },
252 { "loglevel", sLogLevel },
253 { "rhostsauthentication", sRhostsAuthentication },
254 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
255 { "hostbasedauthentication", sHostbasedAuthentication },
256 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
257 { "rsaauthentication", sRSAAuthentication },
258 { "pubkeyauthentication", sPubkeyAuthentication },
259 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
261 { "kerberosauthentication", sKerberosAuthentication },
262 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
263 { "kerberosticketcleanup", sKerberosTicketCleanup },
266 { "kerberostgtpassing", sKerberosTgtPassing },
267 { "afstokenpassing", sAFSTokenPassing },
269 { "passwordauthentication", sPasswordAuthentication },
270 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
271 { "challengeresponseauthentication", sChallengeResponseAuthentication },
272 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
273 { "checkmail", sCheckMail },
274 { "listenaddress", sListenAddress },
275 { "printmotd", sPrintMotd },
276 { "printlastlog", sPrintLastLog },
277 { "ignorerhosts", sIgnoreRhosts },
278 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
279 { "x11forwarding", sX11Forwarding },
280 { "x11displayoffset", sX11DisplayOffset },
281 { "xauthlocation", sXAuthLocation },
282 { "strictmodes", sStrictModes },
283 { "permitemptypasswords", sEmptyPasswd },
284 { "uselogin", sUseLogin },
285 { "keepalive", sKeepAlives },
286 { "allowtcpforwarding", sAllowTcpForwarding },
287 { "allowusers", sAllowUsers },
288 { "denyusers", sDenyUsers },
289 { "allowgroups", sAllowGroups },
290 { "denygroups", sDenyGroups },
291 { "ciphers", sCiphers },
293 { "protocol", sProtocol },
294 { "gatewayports", sGatewayPorts },
295 { "subsystem", sSubsystem },
296 { "maxstartups", sMaxStartups },
297 { "banner", sBanner },
298 { "reversemappingcheck", sReverseMappingCheck },
299 { "clientaliveinterval", sClientAliveInterval },
300 { "clientalivecountmax", sClientAliveCountMax },
305 * Returns the number of the token pointed to by cp or sBadOption.
309 parse_token(const char *cp, const char *filename,
314 for (i = 0; keywords[i].name; i++)
315 if (strcasecmp(cp, keywords[i].name) == 0)
316 return keywords[i].opcode;
318 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
319 filename, linenum, cp);
324 add_listen_addr(ServerOptions *options, char *addr, u_short port)
328 if (options->num_ports == 0)
329 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
331 for (i = 0; i < options->num_ports; i++)
332 add_one_listen_addr(options, addr, options->ports[i]);
334 add_one_listen_addr(options, addr, port);
338 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
340 struct addrinfo hints, *ai, *aitop;
341 char strport[NI_MAXSERV];
344 memset(&hints, 0, sizeof(hints));
345 hints.ai_family = IPv4or6;
346 hints.ai_socktype = SOCK_STREAM;
347 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
348 snprintf(strport, sizeof strport, "%d", port);
349 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
350 fatal("bad addr or host: %s (%s)",
351 addr ? addr : "<NULL>",
352 gai_strerror(gaierr));
353 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
355 ai->ai_next = options->listen_addrs;
356 options->listen_addrs = aitop;
359 /* Reads the server configuration file. */
362 read_server_config(ServerOptions *options, const char *filename)
366 char *cp, **charptr, *arg, *p;
367 int linenum, *intptr, value;
369 ServerOpCodes opcode;
372 f = fopen(filename, "r");
378 while (fgets(line, sizeof(line), f)) {
382 /* Ignore leading whitespace */
385 if (!arg || !*arg || *arg == '#')
389 opcode = parse_token(arg, filename, linenum);
395 /* ignore ports from configfile if cmdline specifies ports */
396 if (options->ports_from_cmdline)
398 if (options->listen_addrs != NULL)
399 fatal("%s line %d: ports must be specified before "
400 "ListenAdress.\n", filename, linenum);
401 if (options->num_ports >= MAX_PORTS)
402 fatal("%s line %d: too many ports.",
405 if (!arg || *arg == '\0')
406 fatal("%s line %d: missing port number.",
408 options->ports[options->num_ports++] = a2port(arg);
409 if (options->ports[options->num_ports-1] == 0)
410 fatal("%s line %d: Badly formatted port number.",
415 intptr = &options->server_key_bits;
418 if (!arg || *arg == '\0') {
419 fprintf(stderr, "%s line %d: missing integer value.\n",
428 case sLoginGraceTime:
429 intptr = &options->login_grace_time;
432 case sKeyRegenerationTime:
433 intptr = &options->key_regeneration_time;
438 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
439 fatal("%s line %d: missing inet addr.",
442 if ((p = strchr(arg, ']')) == NULL)
443 fatal("%s line %d: bad ipv6 inet addr usage.",
446 memmove(p, p+1, strlen(p+1)+1);
447 } else if (((p = strchr(arg, ':')) == NULL) ||
448 (strchr(p+1, ':') != NULL)) {
449 add_listen_addr(options, arg, 0);
457 fatal("%s line %d: bad inet addr:port usage.",
461 if ((port = a2port(p)) == 0)
462 fatal("%s line %d: bad port number.",
464 add_listen_addr(options, arg, port);
466 } else if (*p == '\0')
467 add_listen_addr(options, arg, 0);
469 fatal("%s line %d: bad inet addr usage.",
474 intptr = &options->num_host_key_files;
475 if (*intptr >= MAX_HOSTKEYS) {
477 "%s line %d: too many host keys specified (max %d).\n",
478 filename, linenum, MAX_HOSTKEYS);
481 charptr = &options->host_key_files[*intptr];
484 if (!arg || *arg == '\0') {
485 fprintf(stderr, "%s line %d: missing file name.\n",
489 if (*charptr == NULL) {
490 *charptr = tilde_expand_filename(arg, getuid());
491 /* increase optional counter */
493 *intptr = *intptr + 1;
498 charptr = &options->pid_file;
501 case sPermitRootLogin:
502 intptr = &options->permit_root_login;
504 if (!arg || *arg == '\0') {
505 fprintf(stderr, "%s line %d: missing yes/"
506 "without-password/forced-commands-only/no "
507 "argument.\n", filename, linenum);
510 if (strcmp(arg, "without-password") == 0)
511 value = PERMIT_NO_PASSWD;
512 else if (strcmp(arg, "forced-commands-only") == 0)
513 value = PERMIT_FORCED_ONLY;
514 else if (strcmp(arg, "yes") == 0)
516 else if (strcmp(arg, "no") == 0)
519 fprintf(stderr, "%s line %d: Bad yes/"
520 "without-password/forced-commands-only/no "
521 "argument: %s\n", filename, linenum, arg);
529 intptr = &options->ignore_rhosts;
532 if (!arg || *arg == '\0') {
533 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
537 if (strcmp(arg, "yes") == 0)
539 else if (strcmp(arg, "no") == 0)
542 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
543 filename, linenum, arg);
550 case sIgnoreUserKnownHosts:
551 intptr = &options->ignore_user_known_hosts;
554 case sRhostsAuthentication:
555 intptr = &options->rhosts_authentication;
558 case sRhostsRSAAuthentication:
559 intptr = &options->rhosts_rsa_authentication;
562 case sHostbasedAuthentication:
563 intptr = &options->hostbased_authentication;
566 case sHostbasedUsesNameFromPacketOnly:
567 intptr = &options->hostbased_uses_name_from_packet_only;
570 case sRSAAuthentication:
571 intptr = &options->rsa_authentication;
574 case sPubkeyAuthentication:
575 intptr = &options->pubkey_authentication;
579 case sKerberosAuthentication:
580 intptr = &options->kerberos_authentication;
583 case sKerberosOrLocalPasswd:
584 intptr = &options->kerberos_or_local_passwd;
587 case sKerberosTicketCleanup:
588 intptr = &options->kerberos_ticket_cleanup;
593 case sKerberosTgtPassing:
594 intptr = &options->kerberos_tgt_passing;
597 case sAFSTokenPassing:
598 intptr = &options->afs_token_passing;
602 case sPasswordAuthentication:
603 intptr = &options->password_authentication;
606 case sKbdInteractiveAuthentication:
607 intptr = &options->kbd_interactive_authentication;
611 intptr = &options->check_mail;
614 case sChallengeResponseAuthentication:
615 intptr = &options->challenge_reponse_authentication;
619 intptr = &options->print_motd;
623 intptr = &options->print_lastlog;
627 intptr = &options->x11_forwarding;
630 case sX11DisplayOffset:
631 intptr = &options->x11_display_offset;
635 charptr = &options->xauth_location;
639 intptr = &options->strict_modes;
643 intptr = &options->keepalives;
647 intptr = &options->permit_empty_passwd;
651 intptr = &options->use_login;
655 intptr = &options->gateway_ports;
658 case sReverseMappingCheck:
659 intptr = &options->reverse_mapping_check;
663 intptr = (int *) &options->log_facility;
665 value = log_facility_number(arg);
666 if (value == (SyslogFacility) - 1)
667 fatal("%.200s line %d: unsupported log facility '%s'",
668 filename, linenum, arg ? arg : "<NONE>");
670 *intptr = (SyslogFacility) value;
674 intptr = (int *) &options->log_level;
676 value = log_level_number(arg);
677 if (value == (LogLevel) - 1)
678 fatal("%.200s line %d: unsupported log level '%s'",
679 filename, linenum, arg ? arg : "<NONE>");
681 *intptr = (LogLevel) value;
684 case sAllowTcpForwarding:
685 intptr = &options->allow_tcp_forwarding;
689 while ((arg = strdelim(&cp)) && *arg != '\0') {
690 if (options->num_allow_users >= MAX_ALLOW_USERS)
691 fatal("%s line %d: too many allow users.",
693 options->allow_users[options->num_allow_users++] = xstrdup(arg);
698 while ((arg = strdelim(&cp)) && *arg != '\0') {
699 if (options->num_deny_users >= MAX_DENY_USERS)
700 fatal( "%s line %d: too many deny users.",
702 options->deny_users[options->num_deny_users++] = xstrdup(arg);
707 while ((arg = strdelim(&cp)) && *arg != '\0') {
708 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
709 fatal("%s line %d: too many allow groups.",
711 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
716 while ((arg = strdelim(&cp)) && *arg != '\0') {
717 if (options->num_deny_groups >= MAX_DENY_GROUPS)
718 fatal("%s line %d: too many deny groups.",
720 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
726 if (!arg || *arg == '\0')
727 fatal("%s line %d: Missing argument.", filename, linenum);
728 if (!ciphers_valid(arg))
729 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
730 filename, linenum, arg ? arg : "<NONE>");
731 if (options->ciphers == NULL)
732 options->ciphers = xstrdup(arg);
737 if (!arg || *arg == '\0')
738 fatal("%s line %d: Missing argument.", filename, linenum);
740 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
741 filename, linenum, arg ? arg : "<NONE>");
742 if (options->macs == NULL)
743 options->macs = xstrdup(arg);
747 intptr = &options->protocol;
749 if (!arg || *arg == '\0')
750 fatal("%s line %d: Missing argument.", filename, linenum);
751 value = proto_spec(arg);
752 if (value == SSH_PROTO_UNKNOWN)
753 fatal("%s line %d: Bad protocol spec '%s'.",
754 filename, linenum, arg ? arg : "<NONE>");
755 if (*intptr == SSH_PROTO_UNKNOWN)
760 if(options->num_subsystems >= MAX_SUBSYSTEMS) {
761 fatal("%s line %d: too many subsystems defined.",
765 if (!arg || *arg == '\0')
766 fatal("%s line %d: Missing subsystem name.",
768 for (i = 0; i < options->num_subsystems; i++)
769 if(strcmp(arg, options->subsystem_name[i]) == 0)
770 fatal("%s line %d: Subsystem '%s' already defined.",
771 filename, linenum, arg);
772 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
774 if (!arg || *arg == '\0')
775 fatal("%s line %d: Missing subsystem command.",
777 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
778 options->num_subsystems++;
783 if (!arg || *arg == '\0')
784 fatal("%s line %d: Missing MaxStartups spec.",
786 if (sscanf(arg, "%d:%d:%d",
787 &options->max_startups_begin,
788 &options->max_startups_rate,
789 &options->max_startups) == 3) {
790 if (options->max_startups_begin >
791 options->max_startups ||
792 options->max_startups_rate > 100 ||
793 options->max_startups_rate < 1)
794 fatal("%s line %d: Illegal MaxStartups spec.",
798 intptr = &options->max_startups;
802 charptr = &options->banner;
804 case sClientAliveInterval:
805 intptr = &options->client_alive_interval;
807 case sClientAliveCountMax:
808 intptr = &options->client_alive_count_max;
811 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
812 filename, linenum, arg, opcode);
815 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
817 "%s line %d: garbage at end of line; \"%.200s\".\n",
818 filename, linenum, arg);
823 if (bad_options > 0) {
824 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
825 filename, bad_options);