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.72 2001/03/25 13:16:10 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->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->rsa_authentication = -1;
70 options->pubkey_authentication = -1;
72 options->kerberos_authentication = -1;
73 options->kerberos_or_local_passwd = -1;
74 options->kerberos_ticket_cleanup = -1;
77 options->kerberos_tgt_passing = -1;
78 options->afs_token_passing = -1;
80 options->password_authentication = -1;
81 options->kbd_interactive_authentication = -1;
82 options->challenge_reponse_authentication = -1;
83 options->permit_empty_passwd = -1;
84 options->use_login = -1;
85 options->allow_tcp_forwarding = -1;
86 options->num_allow_users = 0;
87 options->num_deny_users = 0;
88 options->num_allow_groups = 0;
89 options->num_deny_groups = 0;
90 options->ciphers = NULL;
92 options->protocol = SSH_PROTO_UNKNOWN;
93 options->gateway_ports = -1;
94 options->num_subsystems = 0;
95 options->max_startups_begin = -1;
96 options->max_startups_rate = -1;
97 options->max_startups = -1;
98 options->banner = NULL;
99 options->reverse_mapping_check = -1;
103 fill_default_server_options(ServerOptions *options)
105 if (options->protocol == SSH_PROTO_UNKNOWN)
106 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
107 if (options->num_host_key_files == 0) {
108 /* fill default hostkeys for protocols */
109 if (options->protocol & SSH_PROTO_1)
110 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE;
111 if (options->protocol & SSH_PROTO_2)
112 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE;
114 if (options->num_ports == 0)
115 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
116 if (options->listen_addrs == NULL)
117 add_listen_addr(options, NULL);
118 if (options->pid_file == NULL)
119 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
120 if (options->server_key_bits == -1)
121 options->server_key_bits = 768;
122 if (options->login_grace_time == -1)
123 options->login_grace_time = 600;
124 if (options->key_regeneration_time == -1)
125 options->key_regeneration_time = 3600;
126 if (options->permit_root_login == PERMIT_NOT_SET)
127 options->permit_root_login = PERMIT_YES;
128 if (options->ignore_rhosts == -1)
129 options->ignore_rhosts = 1;
130 if (options->ignore_user_known_hosts == -1)
131 options->ignore_user_known_hosts = 0;
132 if (options->check_mail == -1)
133 options->check_mail = 0;
134 if (options->print_motd == -1)
135 options->print_motd = 1;
136 if (options->print_lastlog == -1)
137 options->print_lastlog = 1;
138 if (options->x11_forwarding == -1)
139 options->x11_forwarding = 0;
140 if (options->x11_display_offset == -1)
141 options->x11_display_offset = 10;
143 if (options->xauth_location == NULL)
144 options->xauth_location = XAUTH_PATH;
145 #endif /* XAUTH_PATH */
146 if (options->strict_modes == -1)
147 options->strict_modes = 1;
148 if (options->keepalives == -1)
149 options->keepalives = 1;
150 if (options->log_facility == (SyslogFacility) (-1))
151 options->log_facility = SYSLOG_FACILITY_AUTH;
152 if (options->log_level == (LogLevel) (-1))
153 options->log_level = SYSLOG_LEVEL_INFO;
154 if (options->rhosts_authentication == -1)
155 options->rhosts_authentication = 0;
156 if (options->rhosts_rsa_authentication == -1)
157 options->rhosts_rsa_authentication = 0;
158 if (options->rsa_authentication == -1)
159 options->rsa_authentication = 1;
160 if (options->pubkey_authentication == -1)
161 options->pubkey_authentication = 1;
163 if (options->kerberos_authentication == -1)
164 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
165 if (options->kerberos_or_local_passwd == -1)
166 options->kerberos_or_local_passwd = 1;
167 if (options->kerberos_ticket_cleanup == -1)
168 options->kerberos_ticket_cleanup = 1;
171 if (options->kerberos_tgt_passing == -1)
172 options->kerberos_tgt_passing = 0;
173 if (options->afs_token_passing == -1)
174 options->afs_token_passing = k_hasafs();
176 if (options->password_authentication == -1)
177 options->password_authentication = 1;
178 if (options->kbd_interactive_authentication == -1)
179 options->kbd_interactive_authentication = 0;
180 if (options->challenge_reponse_authentication == -1)
181 options->challenge_reponse_authentication = 1;
182 if (options->permit_empty_passwd == -1)
183 options->permit_empty_passwd = 0;
184 if (options->use_login == -1)
185 options->use_login = 0;
186 if (options->allow_tcp_forwarding == -1)
187 options->allow_tcp_forwarding = 1;
188 if (options->gateway_ports == -1)
189 options->gateway_ports = 0;
190 if (options->max_startups == -1)
191 options->max_startups = 10;
192 if (options->max_startups_rate == -1)
193 options->max_startups_rate = 100; /* 100% */
194 if (options->max_startups_begin == -1)
195 options->max_startups_begin = options->max_startups;
196 if (options->reverse_mapping_check == -1)
197 options->reverse_mapping_check = 0;
200 /* Keyword tokens. */
202 sBadOption, /* == unknown option */
203 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
204 sPermitRootLogin, sLogFacility, sLogLevel,
205 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
207 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
210 sKerberosTgtPassing, sAFSTokenPassing,
212 sChallengeResponseAuthentication,
213 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
214 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
215 sX11Forwarding, sX11DisplayOffset,
216 sStrictModes, sEmptyPasswd, sKeepAlives, sCheckMail,
217 sUseLogin, sAllowTcpForwarding,
218 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
219 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
220 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
221 sBanner, sReverseMappingCheck
224 /* Textual representation of the tokens. */
227 ServerOpCodes opcode;
230 { "hostkey", sHostKeyFile },
231 { "hostdsakey", sHostKeyFile }, /* alias */
232 { "pidfile", sPidFile },
233 { "serverkeybits", sServerKeyBits },
234 { "logingracetime", sLoginGraceTime },
235 { "keyregenerationinterval", sKeyRegenerationTime },
236 { "permitrootlogin", sPermitRootLogin },
237 { "syslogfacility", sLogFacility },
238 { "loglevel", sLogLevel },
239 { "rhostsauthentication", sRhostsAuthentication },
240 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
241 { "rsaauthentication", sRSAAuthentication },
242 { "pubkeyauthentication", sPubkeyAuthentication },
243 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
245 { "kerberosauthentication", sKerberosAuthentication },
246 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
247 { "kerberosticketcleanup", sKerberosTicketCleanup },
250 { "kerberostgtpassing", sKerberosTgtPassing },
251 { "afstokenpassing", sAFSTokenPassing },
253 { "passwordauthentication", sPasswordAuthentication },
254 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
255 { "challengeresponseauthentication", sChallengeResponseAuthentication },
256 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
257 { "checkmail", sCheckMail },
258 { "listenaddress", sListenAddress },
259 { "printmotd", sPrintMotd },
260 { "printlastlog", sPrintLastLog },
261 { "ignorerhosts", sIgnoreRhosts },
262 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
263 { "x11forwarding", sX11Forwarding },
264 { "x11displayoffset", sX11DisplayOffset },
265 { "xauthlocation", sXAuthLocation },
266 { "strictmodes", sStrictModes },
267 { "permitemptypasswords", sEmptyPasswd },
268 { "uselogin", sUseLogin },
269 { "keepalive", sKeepAlives },
270 { "allowtcpforwarding", sAllowTcpForwarding },
271 { "allowusers", sAllowUsers },
272 { "denyusers", sDenyUsers },
273 { "allowgroups", sAllowGroups },
274 { "denygroups", sDenyGroups },
275 { "ciphers", sCiphers },
277 { "protocol", sProtocol },
278 { "gatewayports", sGatewayPorts },
279 { "subsystem", sSubsystem },
280 { "maxstartups", sMaxStartups },
281 { "banner", sBanner },
282 { "reversemappingcheck", sReverseMappingCheck },
287 * Returns the number of the token pointed to by cp of length len. Never
288 * returns if the token is not known.
292 parse_token(const char *cp, const char *filename,
297 for (i = 0; keywords[i].name; i++)
298 if (strcasecmp(cp, keywords[i].name) == 0)
299 return keywords[i].opcode;
301 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
302 filename, linenum, cp);
310 add_listen_addr(ServerOptions *options, char *addr)
312 struct addrinfo hints, *ai, *aitop;
313 char strport[NI_MAXSERV];
317 if (options->num_ports == 0)
318 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
319 for (i = 0; i < options->num_ports; i++) {
320 memset(&hints, 0, sizeof(hints));
321 hints.ai_family = IPv4or6;
322 hints.ai_socktype = SOCK_STREAM;
323 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
324 snprintf(strport, sizeof strport, "%d", options->ports[i]);
325 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
326 fatal("bad addr or host: %s (%s)",
327 addr ? addr : "<NULL>",
328 gai_strerror(gaierr));
329 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
331 ai->ai_next = options->listen_addrs;
332 options->listen_addrs = aitop;
336 /* Reads the server configuration file. */
339 read_server_config(ServerOptions *options, const char *filename)
343 char *cp, **charptr, *arg;
344 int linenum, *intptr, value;
346 ServerOpCodes opcode;
349 f = fopen(filename, "r");
355 while (fgets(line, sizeof(line), f)) {
359 /* Ignore leading whitespace */
362 if (!arg || !*arg || *arg == '#')
366 opcode = parse_token(arg, filename, linenum);
372 /* ignore ports from configfile if cmdline specifies ports */
373 if (options->ports_from_cmdline)
375 if (options->listen_addrs != NULL)
376 fatal("%s line %d: ports must be specified before "
377 "ListenAdress.\n", filename, linenum);
378 if (options->num_ports >= MAX_PORTS)
379 fatal("%s line %d: too many ports.",
382 if (!arg || *arg == '\0')
383 fatal("%s line %d: missing port number.",
385 options->ports[options->num_ports++] = atoi(arg);
389 intptr = &options->server_key_bits;
392 if (!arg || *arg == '\0') {
393 fprintf(stderr, "%s line %d: missing integer value.\n",
402 case sLoginGraceTime:
403 intptr = &options->login_grace_time;
406 case sKeyRegenerationTime:
407 intptr = &options->key_regeneration_time;
412 if (!arg || *arg == '\0')
413 fatal("%s line %d: missing inet addr.",
415 add_listen_addr(options, arg);
419 intptr = &options->num_host_key_files;
420 if (*intptr >= MAX_HOSTKEYS) {
422 "%s line %d: too many host keys specified (max %d).\n",
423 filename, linenum, MAX_HOSTKEYS);
426 charptr = &options->host_key_files[*intptr];
429 if (!arg || *arg == '\0') {
430 fprintf(stderr, "%s line %d: missing file name.\n",
434 if (*charptr == NULL) {
435 *charptr = tilde_expand_filename(arg, getuid());
436 /* increase optional counter */
438 *intptr = *intptr + 1;
443 charptr = &options->pid_file;
446 case sPermitRootLogin:
447 intptr = &options->permit_root_login;
449 if (!arg || *arg == '\0') {
450 fprintf(stderr, "%s line %d: missing yes/"
451 "without-password/forced-commands-only/no "
452 "argument.\n", filename, linenum);
455 if (strcmp(arg, "without-password") == 0)
456 value = PERMIT_NO_PASSWD;
457 else if (strcmp(arg, "forced-commands-only") == 0)
458 value = PERMIT_FORCED_ONLY;
459 else if (strcmp(arg, "yes") == 0)
461 else if (strcmp(arg, "no") == 0)
464 fprintf(stderr, "%s line %d: Bad yes/"
465 "without-password/forced-commands-only/no "
466 "argument: %s\n", filename, linenum, arg);
474 intptr = &options->ignore_rhosts;
477 if (!arg || *arg == '\0') {
478 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
482 if (strcmp(arg, "yes") == 0)
484 else if (strcmp(arg, "no") == 0)
487 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
488 filename, linenum, arg);
495 case sIgnoreUserKnownHosts:
496 intptr = &options->ignore_user_known_hosts;
499 case sRhostsAuthentication:
500 intptr = &options->rhosts_authentication;
503 case sRhostsRSAAuthentication:
504 intptr = &options->rhosts_rsa_authentication;
507 case sRSAAuthentication:
508 intptr = &options->rsa_authentication;
511 case sPubkeyAuthentication:
512 intptr = &options->pubkey_authentication;
516 case sKerberosAuthentication:
517 intptr = &options->kerberos_authentication;
520 case sKerberosOrLocalPasswd:
521 intptr = &options->kerberos_or_local_passwd;
524 case sKerberosTicketCleanup:
525 intptr = &options->kerberos_ticket_cleanup;
530 case sKerberosTgtPassing:
531 intptr = &options->kerberos_tgt_passing;
534 case sAFSTokenPassing:
535 intptr = &options->afs_token_passing;
539 case sPasswordAuthentication:
540 intptr = &options->password_authentication;
543 case sKbdInteractiveAuthentication:
544 intptr = &options->kbd_interactive_authentication;
548 intptr = &options->check_mail;
551 case sChallengeResponseAuthentication:
552 intptr = &options->challenge_reponse_authentication;
556 intptr = &options->print_motd;
560 intptr = &options->print_lastlog;
564 intptr = &options->x11_forwarding;
567 case sX11DisplayOffset:
568 intptr = &options->x11_display_offset;
572 charptr = &options->xauth_location;
576 intptr = &options->strict_modes;
580 intptr = &options->keepalives;
584 intptr = &options->permit_empty_passwd;
588 intptr = &options->use_login;
592 intptr = &options->gateway_ports;
595 case sReverseMappingCheck:
596 intptr = &options->reverse_mapping_check;
600 intptr = (int *) &options->log_facility;
602 value = log_facility_number(arg);
603 if (value == (SyslogFacility) - 1)
604 fatal("%.200s line %d: unsupported log facility '%s'",
605 filename, linenum, arg ? arg : "<NONE>");
607 *intptr = (SyslogFacility) value;
611 intptr = (int *) &options->log_level;
613 value = log_level_number(arg);
614 if (value == (LogLevel) - 1)
615 fatal("%.200s line %d: unsupported log level '%s'",
616 filename, linenum, arg ? arg : "<NONE>");
618 *intptr = (LogLevel) value;
621 case sAllowTcpForwarding:
622 intptr = &options->allow_tcp_forwarding;
626 while ((arg = strdelim(&cp)) && *arg != '\0') {
627 if (options->num_allow_users >= MAX_ALLOW_USERS)
628 fatal("%s line %d: too many allow users.",
630 options->allow_users[options->num_allow_users++] = xstrdup(arg);
635 while ((arg = strdelim(&cp)) && *arg != '\0') {
636 if (options->num_deny_users >= MAX_DENY_USERS)
637 fatal( "%s line %d: too many deny users.",
639 options->deny_users[options->num_deny_users++] = xstrdup(arg);
644 while ((arg = strdelim(&cp)) && *arg != '\0') {
645 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
646 fatal("%s line %d: too many allow groups.",
648 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
653 while ((arg = strdelim(&cp)) && *arg != '\0') {
654 if (options->num_deny_groups >= MAX_DENY_GROUPS)
655 fatal("%s line %d: too many deny groups.",
657 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
663 if (!arg || *arg == '\0')
664 fatal("%s line %d: Missing argument.", filename, linenum);
665 if (!ciphers_valid(arg))
666 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
667 filename, linenum, arg ? arg : "<NONE>");
668 if (options->ciphers == NULL)
669 options->ciphers = xstrdup(arg);
674 if (!arg || *arg == '\0')
675 fatal("%s line %d: Missing argument.", filename, linenum);
677 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
678 filename, linenum, arg ? arg : "<NONE>");
679 if (options->macs == NULL)
680 options->macs = xstrdup(arg);
684 intptr = &options->protocol;
686 if (!arg || *arg == '\0')
687 fatal("%s line %d: Missing argument.", filename, linenum);
688 value = proto_spec(arg);
689 if (value == SSH_PROTO_UNKNOWN)
690 fatal("%s line %d: Bad protocol spec '%s'.",
691 filename, linenum, arg ? arg : "<NONE>");
692 if (*intptr == SSH_PROTO_UNKNOWN)
697 if(options->num_subsystems >= MAX_SUBSYSTEMS) {
698 fatal("%s line %d: too many subsystems defined.",
702 if (!arg || *arg == '\0')
703 fatal("%s line %d: Missing subsystem name.",
705 for (i = 0; i < options->num_subsystems; i++)
706 if(strcmp(arg, options->subsystem_name[i]) == 0)
707 fatal("%s line %d: Subsystem '%s' already defined.",
708 filename, linenum, arg);
709 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
711 if (!arg || *arg == '\0')
712 fatal("%s line %d: Missing subsystem command.",
714 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
715 options->num_subsystems++;
720 if (!arg || *arg == '\0')
721 fatal("%s line %d: Missing MaxStartups spec.",
723 if (sscanf(arg, "%d:%d:%d",
724 &options->max_startups_begin,
725 &options->max_startups_rate,
726 &options->max_startups) == 3) {
727 if (options->max_startups_begin >
728 options->max_startups ||
729 options->max_startups_rate > 100 ||
730 options->max_startups_rate < 1)
731 fatal("%s line %d: Illegal MaxStartups spec.",
735 intptr = &options->max_startups;
739 charptr = &options->banner;
743 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
744 filename, linenum, arg, opcode);
747 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
749 "%s line %d: garbage at end of line; \"%.200s\".\n",
750 filename, linenum, arg);
755 if (bad_options > 0) {
756 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
757 filename, bad_options);