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.71 2001/03/05 15:44:51 stevesk Exp $");
27 #include "pathnames.h"
28 #include "tildexpand.h"
34 /* add listen address */
35 void add_listen_addr(ServerOptions *options, char *addr);
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->check_mail = -1;
59 options->x11_forwarding = -1;
60 options->x11_display_offset = -1;
61 options->xauth_location = NULL;
62 options->strict_modes = -1;
63 options->keepalives = -1;
64 options->log_facility = (SyslogFacility) - 1;
65 options->log_level = (LogLevel) - 1;
66 options->rhosts_authentication = -1;
67 options->rhosts_rsa_authentication = -1;
68 options->rsa_authentication = -1;
69 options->pubkey_authentication = -1;
71 options->kerberos_authentication = -1;
72 options->kerberos_or_local_passwd = -1;
73 options->kerberos_ticket_cleanup = -1;
76 options->kerberos_tgt_passing = -1;
77 options->afs_token_passing = -1;
79 options->password_authentication = -1;
80 options->kbd_interactive_authentication = -1;
81 options->challenge_reponse_authentication = -1;
82 options->permit_empty_passwd = -1;
83 options->use_login = -1;
84 options->allow_tcp_forwarding = -1;
85 options->num_allow_users = 0;
86 options->num_deny_users = 0;
87 options->num_allow_groups = 0;
88 options->num_deny_groups = 0;
89 options->ciphers = NULL;
91 options->protocol = SSH_PROTO_UNKNOWN;
92 options->gateway_ports = -1;
93 options->num_subsystems = 0;
94 options->max_startups_begin = -1;
95 options->max_startups_rate = -1;
96 options->max_startups = -1;
97 options->banner = NULL;
98 options->reverse_mapping_check = -1;
102 fill_default_server_options(ServerOptions *options)
104 if (options->protocol == SSH_PROTO_UNKNOWN)
105 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
106 if (options->num_host_key_files == 0) {
107 /* fill default hostkeys for protocols */
108 if (options->protocol & SSH_PROTO_1)
109 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE;
110 if (options->protocol & SSH_PROTO_2)
111 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE;
113 if (options->num_ports == 0)
114 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
115 if (options->listen_addrs == NULL)
116 add_listen_addr(options, NULL);
117 if (options->pid_file == NULL)
118 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
119 if (options->server_key_bits == -1)
120 options->server_key_bits = 768;
121 if (options->login_grace_time == -1)
122 options->login_grace_time = 600;
123 if (options->key_regeneration_time == -1)
124 options->key_regeneration_time = 3600;
125 if (options->permit_root_login == PERMIT_NOT_SET)
126 options->permit_root_login = PERMIT_YES;
127 if (options->ignore_rhosts == -1)
128 options->ignore_rhosts = 1;
129 if (options->ignore_user_known_hosts == -1)
130 options->ignore_user_known_hosts = 0;
131 if (options->check_mail == -1)
132 options->check_mail = 0;
133 if (options->print_motd == -1)
134 options->print_motd = 1;
135 if (options->x11_forwarding == -1)
136 options->x11_forwarding = 0;
137 if (options->x11_display_offset == -1)
138 options->x11_display_offset = 10;
140 if (options->xauth_location == NULL)
141 options->xauth_location = XAUTH_PATH;
142 #endif /* XAUTH_PATH */
143 if (options->strict_modes == -1)
144 options->strict_modes = 1;
145 if (options->keepalives == -1)
146 options->keepalives = 1;
147 if (options->log_facility == (SyslogFacility) (-1))
148 options->log_facility = SYSLOG_FACILITY_AUTH;
149 if (options->log_level == (LogLevel) (-1))
150 options->log_level = SYSLOG_LEVEL_INFO;
151 if (options->rhosts_authentication == -1)
152 options->rhosts_authentication = 0;
153 if (options->rhosts_rsa_authentication == -1)
154 options->rhosts_rsa_authentication = 0;
155 if (options->rsa_authentication == -1)
156 options->rsa_authentication = 1;
157 if (options->pubkey_authentication == -1)
158 options->pubkey_authentication = 1;
160 if (options->kerberos_authentication == -1)
161 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
162 if (options->kerberos_or_local_passwd == -1)
163 options->kerberos_or_local_passwd = 1;
164 if (options->kerberos_ticket_cleanup == -1)
165 options->kerberos_ticket_cleanup = 1;
168 if (options->kerberos_tgt_passing == -1)
169 options->kerberos_tgt_passing = 0;
170 if (options->afs_token_passing == -1)
171 options->afs_token_passing = k_hasafs();
173 if (options->password_authentication == -1)
174 options->password_authentication = 1;
175 if (options->kbd_interactive_authentication == -1)
176 options->kbd_interactive_authentication = 0;
177 if (options->challenge_reponse_authentication == -1)
178 options->challenge_reponse_authentication = 1;
179 if (options->permit_empty_passwd == -1)
180 options->permit_empty_passwd = 0;
181 if (options->use_login == -1)
182 options->use_login = 0;
183 if (options->allow_tcp_forwarding == -1)
184 options->allow_tcp_forwarding = 1;
185 if (options->gateway_ports == -1)
186 options->gateway_ports = 0;
187 if (options->max_startups == -1)
188 options->max_startups = 10;
189 if (options->max_startups_rate == -1)
190 options->max_startups_rate = 100; /* 100% */
191 if (options->max_startups_begin == -1)
192 options->max_startups_begin = options->max_startups;
193 if (options->reverse_mapping_check == -1)
194 options->reverse_mapping_check = 0;
197 /* Keyword tokens. */
199 sBadOption, /* == unknown option */
200 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
201 sPermitRootLogin, sLogFacility, sLogLevel,
202 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
204 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
207 sKerberosTgtPassing, sAFSTokenPassing,
209 sChallengeResponseAuthentication,
210 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
211 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
212 sStrictModes, sEmptyPasswd, sKeepAlives, sCheckMail,
213 sUseLogin, sAllowTcpForwarding,
214 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
215 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
216 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
217 sBanner, sReverseMappingCheck
220 /* Textual representation of the tokens. */
223 ServerOpCodes opcode;
226 { "hostkey", sHostKeyFile },
227 { "hostdsakey", sHostKeyFile }, /* alias */
228 { "pidfile", sPidFile },
229 { "serverkeybits", sServerKeyBits },
230 { "logingracetime", sLoginGraceTime },
231 { "keyregenerationinterval", sKeyRegenerationTime },
232 { "permitrootlogin", sPermitRootLogin },
233 { "syslogfacility", sLogFacility },
234 { "loglevel", sLogLevel },
235 { "rhostsauthentication", sRhostsAuthentication },
236 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
237 { "rsaauthentication", sRSAAuthentication },
238 { "pubkeyauthentication", sPubkeyAuthentication },
239 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
241 { "kerberosauthentication", sKerberosAuthentication },
242 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
243 { "kerberosticketcleanup", sKerberosTicketCleanup },
246 { "kerberostgtpassing", sKerberosTgtPassing },
247 { "afstokenpassing", sAFSTokenPassing },
249 { "passwordauthentication", sPasswordAuthentication },
250 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
251 { "challengeresponseauthentication", sChallengeResponseAuthentication },
252 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
253 { "checkmail", sCheckMail },
254 { "listenaddress", sListenAddress },
255 { "printmotd", sPrintMotd },
256 { "ignorerhosts", sIgnoreRhosts },
257 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
258 { "x11forwarding", sX11Forwarding },
259 { "x11displayoffset", sX11DisplayOffset },
260 { "xauthlocation", sXAuthLocation },
261 { "strictmodes", sStrictModes },
262 { "permitemptypasswords", sEmptyPasswd },
263 { "uselogin", sUseLogin },
264 { "keepalive", sKeepAlives },
265 { "allowtcpforwarding", sAllowTcpForwarding },
266 { "allowusers", sAllowUsers },
267 { "denyusers", sDenyUsers },
268 { "allowgroups", sAllowGroups },
269 { "denygroups", sDenyGroups },
270 { "ciphers", sCiphers },
272 { "protocol", sProtocol },
273 { "gatewayports", sGatewayPorts },
274 { "subsystem", sSubsystem },
275 { "maxstartups", sMaxStartups },
276 { "banner", sBanner },
277 { "reversemappingcheck", sReverseMappingCheck },
282 * Returns the number of the token pointed to by cp of length len. Never
283 * returns if the token is not known.
287 parse_token(const char *cp, const char *filename,
292 for (i = 0; keywords[i].name; i++)
293 if (strcasecmp(cp, keywords[i].name) == 0)
294 return keywords[i].opcode;
296 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
297 filename, linenum, cp);
305 add_listen_addr(ServerOptions *options, char *addr)
307 struct addrinfo hints, *ai, *aitop;
308 char strport[NI_MAXSERV];
312 if (options->num_ports == 0)
313 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
314 for (i = 0; i < options->num_ports; i++) {
315 memset(&hints, 0, sizeof(hints));
316 hints.ai_family = IPv4or6;
317 hints.ai_socktype = SOCK_STREAM;
318 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
319 snprintf(strport, sizeof strport, "%d", options->ports[i]);
320 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
321 fatal("bad addr or host: %s (%s)",
322 addr ? addr : "<NULL>",
323 gai_strerror(gaierr));
324 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
326 ai->ai_next = options->listen_addrs;
327 options->listen_addrs = aitop;
331 /* Reads the server configuration file. */
334 read_server_config(ServerOptions *options, const char *filename)
338 char *cp, **charptr, *arg;
339 int linenum, *intptr, value;
341 ServerOpCodes opcode;
344 f = fopen(filename, "r");
350 while (fgets(line, sizeof(line), f)) {
354 /* Ignore leading whitespace */
357 if (!arg || !*arg || *arg == '#')
361 opcode = parse_token(arg, filename, linenum);
367 /* ignore ports from configfile if cmdline specifies ports */
368 if (options->ports_from_cmdline)
370 if (options->listen_addrs != NULL)
371 fatal("%s line %d: ports must be specified before "
372 "ListenAdress.\n", filename, linenum);
373 if (options->num_ports >= MAX_PORTS)
374 fatal("%s line %d: too many ports.",
377 if (!arg || *arg == '\0')
378 fatal("%s line %d: missing port number.",
380 options->ports[options->num_ports++] = atoi(arg);
384 intptr = &options->server_key_bits;
387 if (!arg || *arg == '\0') {
388 fprintf(stderr, "%s line %d: missing integer value.\n",
397 case sLoginGraceTime:
398 intptr = &options->login_grace_time;
401 case sKeyRegenerationTime:
402 intptr = &options->key_regeneration_time;
407 if (!arg || *arg == '\0')
408 fatal("%s line %d: missing inet addr.",
410 add_listen_addr(options, arg);
414 intptr = &options->num_host_key_files;
415 if (*intptr >= MAX_HOSTKEYS) {
417 "%s line %d: too many host keys specified (max %d).\n",
418 filename, linenum, MAX_HOSTKEYS);
421 charptr = &options->host_key_files[*intptr];
424 if (!arg || *arg == '\0') {
425 fprintf(stderr, "%s line %d: missing file name.\n",
429 if (*charptr == NULL) {
430 *charptr = tilde_expand_filename(arg, getuid());
431 /* increase optional counter */
433 *intptr = *intptr + 1;
438 charptr = &options->pid_file;
441 case sPermitRootLogin:
442 intptr = &options->permit_root_login;
444 if (!arg || *arg == '\0') {
445 fprintf(stderr, "%s line %d: missing yes/"
446 "without-password/forced-commands-only/no "
447 "argument.\n", filename, linenum);
450 if (strcmp(arg, "without-password") == 0)
451 value = PERMIT_NO_PASSWD;
452 else if (strcmp(arg, "forced-commands-only") == 0)
453 value = PERMIT_FORCED_ONLY;
454 else if (strcmp(arg, "yes") == 0)
456 else if (strcmp(arg, "no") == 0)
459 fprintf(stderr, "%s line %d: Bad yes/"
460 "without-password/forced-commands-only/no "
461 "argument: %s\n", filename, linenum, arg);
469 intptr = &options->ignore_rhosts;
472 if (!arg || *arg == '\0') {
473 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
477 if (strcmp(arg, "yes") == 0)
479 else if (strcmp(arg, "no") == 0)
482 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
483 filename, linenum, arg);
490 case sIgnoreUserKnownHosts:
491 intptr = &options->ignore_user_known_hosts;
494 case sRhostsAuthentication:
495 intptr = &options->rhosts_authentication;
498 case sRhostsRSAAuthentication:
499 intptr = &options->rhosts_rsa_authentication;
502 case sRSAAuthentication:
503 intptr = &options->rsa_authentication;
506 case sPubkeyAuthentication:
507 intptr = &options->pubkey_authentication;
511 case sKerberosAuthentication:
512 intptr = &options->kerberos_authentication;
515 case sKerberosOrLocalPasswd:
516 intptr = &options->kerberos_or_local_passwd;
519 case sKerberosTicketCleanup:
520 intptr = &options->kerberos_ticket_cleanup;
525 case sKerberosTgtPassing:
526 intptr = &options->kerberos_tgt_passing;
529 case sAFSTokenPassing:
530 intptr = &options->afs_token_passing;
534 case sPasswordAuthentication:
535 intptr = &options->password_authentication;
538 case sKbdInteractiveAuthentication:
539 intptr = &options->kbd_interactive_authentication;
543 intptr = &options->check_mail;
546 case sChallengeResponseAuthentication:
547 intptr = &options->challenge_reponse_authentication;
551 intptr = &options->print_motd;
555 intptr = &options->x11_forwarding;
558 case sX11DisplayOffset:
559 intptr = &options->x11_display_offset;
563 charptr = &options->xauth_location;
567 intptr = &options->strict_modes;
571 intptr = &options->keepalives;
575 intptr = &options->permit_empty_passwd;
579 intptr = &options->use_login;
583 intptr = &options->gateway_ports;
586 case sReverseMappingCheck:
587 intptr = &options->reverse_mapping_check;
591 intptr = (int *) &options->log_facility;
593 value = log_facility_number(arg);
594 if (value == (SyslogFacility) - 1)
595 fatal("%.200s line %d: unsupported log facility '%s'",
596 filename, linenum, arg ? arg : "<NONE>");
598 *intptr = (SyslogFacility) value;
602 intptr = (int *) &options->log_level;
604 value = log_level_number(arg);
605 if (value == (LogLevel) - 1)
606 fatal("%.200s line %d: unsupported log level '%s'",
607 filename, linenum, arg ? arg : "<NONE>");
609 *intptr = (LogLevel) value;
612 case sAllowTcpForwarding:
613 intptr = &options->allow_tcp_forwarding;
617 while ((arg = strdelim(&cp)) && *arg != '\0') {
618 if (options->num_allow_users >= MAX_ALLOW_USERS)
619 fatal("%s line %d: too many allow users.",
621 options->allow_users[options->num_allow_users++] = xstrdup(arg);
626 while ((arg = strdelim(&cp)) && *arg != '\0') {
627 if (options->num_deny_users >= MAX_DENY_USERS)
628 fatal( "%s line %d: too many deny users.",
630 options->deny_users[options->num_deny_users++] = xstrdup(arg);
635 while ((arg = strdelim(&cp)) && *arg != '\0') {
636 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
637 fatal("%s line %d: too many allow groups.",
639 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
644 while ((arg = strdelim(&cp)) && *arg != '\0') {
645 if (options->num_deny_groups >= MAX_DENY_GROUPS)
646 fatal("%s line %d: too many deny groups.",
648 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
654 if (!arg || *arg == '\0')
655 fatal("%s line %d: Missing argument.", filename, linenum);
656 if (!ciphers_valid(arg))
657 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
658 filename, linenum, arg ? arg : "<NONE>");
659 if (options->ciphers == NULL)
660 options->ciphers = xstrdup(arg);
665 if (!arg || *arg == '\0')
666 fatal("%s line %d: Missing argument.", filename, linenum);
668 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
669 filename, linenum, arg ? arg : "<NONE>");
670 if (options->macs == NULL)
671 options->macs = xstrdup(arg);
675 intptr = &options->protocol;
677 if (!arg || *arg == '\0')
678 fatal("%s line %d: Missing argument.", filename, linenum);
679 value = proto_spec(arg);
680 if (value == SSH_PROTO_UNKNOWN)
681 fatal("%s line %d: Bad protocol spec '%s'.",
682 filename, linenum, arg ? arg : "<NONE>");
683 if (*intptr == SSH_PROTO_UNKNOWN)
688 if(options->num_subsystems >= MAX_SUBSYSTEMS) {
689 fatal("%s line %d: too many subsystems defined.",
693 if (!arg || *arg == '\0')
694 fatal("%s line %d: Missing subsystem name.",
696 for (i = 0; i < options->num_subsystems; i++)
697 if(strcmp(arg, options->subsystem_name[i]) == 0)
698 fatal("%s line %d: Subsystem '%s' already defined.",
699 filename, linenum, arg);
700 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
702 if (!arg || *arg == '\0')
703 fatal("%s line %d: Missing subsystem command.",
705 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
706 options->num_subsystems++;
711 if (!arg || *arg == '\0')
712 fatal("%s line %d: Missing MaxStartups spec.",
714 if (sscanf(arg, "%d:%d:%d",
715 &options->max_startups_begin,
716 &options->max_startups_rate,
717 &options->max_startups) == 3) {
718 if (options->max_startups_begin >
719 options->max_startups ||
720 options->max_startups_rate > 100 ||
721 options->max_startups_rate < 1)
722 fatal("%s line %d: Illegal MaxStartups spec.",
726 intptr = &options->max_startups;
730 charptr = &options->banner;
734 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
735 filename, linenum, arg, opcode);
738 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
740 "%s line %d: garbage at end of line; \"%.200s\".\n",
741 filename, linenum, arg);
746 if (bad_options > 0) {
747 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
748 filename, bad_options);