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.66 2001/02/11 12:59:25 markus 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 = -1;
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 == -1)
126 options->permit_root_login = 1; /* 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, sRandomSeedFile, 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 { "randomseed", sRandomSeedFile },
265 { "keepalive", sKeepAlives },
266 { "allowtcpforwarding", sAllowTcpForwarding },
267 { "allowusers", sAllowUsers },
268 { "denyusers", sDenyUsers },
269 { "allowgroups", sAllowGroups },
270 { "denygroups", sDenyGroups },
271 { "ciphers", sCiphers },
273 { "protocol", sProtocol },
274 { "gatewayports", sGatewayPorts },
275 { "subsystem", sSubsystem },
276 { "maxstartups", sMaxStartups },
277 { "banner", sBanner },
278 { "reversemappingcheck", sReverseMappingCheck },
283 * Returns the number of the token pointed to by cp of length len. Never
284 * returns if the token is not known.
288 parse_token(const char *cp, const char *filename,
293 for (i = 0; keywords[i].name; i++)
294 if (strcasecmp(cp, keywords[i].name) == 0)
295 return keywords[i].opcode;
297 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
298 filename, linenum, cp);
306 add_listen_addr(ServerOptions *options, char *addr)
308 struct addrinfo hints, *ai, *aitop;
309 char strport[NI_MAXSERV];
313 if (options->num_ports == 0)
314 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
315 for (i = 0; i < options->num_ports; i++) {
316 memset(&hints, 0, sizeof(hints));
317 hints.ai_family = IPv4or6;
318 hints.ai_socktype = SOCK_STREAM;
319 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
320 snprintf(strport, sizeof strport, "%d", options->ports[i]);
321 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
322 fatal("bad addr or host: %s (%s)\n",
323 addr ? addr : "<NULL>",
324 gai_strerror(gaierr));
325 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
327 ai->ai_next = options->listen_addrs;
328 options->listen_addrs = aitop;
332 /* Reads the server configuration file. */
335 read_server_config(ServerOptions *options, const char *filename)
339 char *cp, **charptr, *arg;
340 int linenum, *intptr, value;
342 ServerOpCodes opcode;
345 f = fopen(filename, "r");
351 while (fgets(line, sizeof(line), f)) {
355 /* Ignore leading whitespace */
358 if (!arg || !*arg || *arg == '#')
362 opcode = parse_token(arg, filename, linenum);
368 /* ignore ports from configfile if cmdline specifies ports */
369 if (options->ports_from_cmdline)
371 if (options->listen_addrs != NULL)
372 fatal("%s line %d: ports must be specified before "
373 "ListenAdress.\n", filename, linenum);
374 if (options->num_ports >= MAX_PORTS)
375 fatal("%s line %d: too many ports.\n",
378 if (!arg || *arg == '\0')
379 fatal("%s line %d: missing port number.\n",
381 options->ports[options->num_ports++] = atoi(arg);
385 intptr = &options->server_key_bits;
388 if (!arg || *arg == '\0') {
389 fprintf(stderr, "%s line %d: missing integer value.\n",
398 case sLoginGraceTime:
399 intptr = &options->login_grace_time;
402 case sKeyRegenerationTime:
403 intptr = &options->key_regeneration_time;
408 if (!arg || *arg == '\0')
409 fatal("%s line %d: missing inet addr.\n",
411 add_listen_addr(options, arg);
415 intptr = &options->num_host_key_files;
416 if (*intptr >= MAX_HOSTKEYS) {
417 fprintf(stderr, "%s line %d: to 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 sRandomSeedFile:
442 fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
447 case sPermitRootLogin:
448 intptr = &options->permit_root_login;
450 if (!arg || *arg == '\0') {
451 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
455 if (strcmp(arg, "without-password") == 0)
457 else if (strcmp(arg, "yes") == 0)
459 else if (strcmp(arg, "no") == 0)
462 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
463 filename, linenum, arg);
471 intptr = &options->ignore_rhosts;
474 if (!arg || *arg == '\0') {
475 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
479 if (strcmp(arg, "yes") == 0)
481 else if (strcmp(arg, "no") == 0)
484 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
485 filename, linenum, arg);
492 case sIgnoreUserKnownHosts:
493 intptr = &options->ignore_user_known_hosts;
496 case sRhostsAuthentication:
497 intptr = &options->rhosts_authentication;
500 case sRhostsRSAAuthentication:
501 intptr = &options->rhosts_rsa_authentication;
504 case sRSAAuthentication:
505 intptr = &options->rsa_authentication;
508 case sPubkeyAuthentication:
509 intptr = &options->pubkey_authentication;
513 case sKerberosAuthentication:
514 intptr = &options->kerberos_authentication;
517 case sKerberosOrLocalPasswd:
518 intptr = &options->kerberos_or_local_passwd;
521 case sKerberosTicketCleanup:
522 intptr = &options->kerberos_ticket_cleanup;
527 case sKerberosTgtPassing:
528 intptr = &options->kerberos_tgt_passing;
531 case sAFSTokenPassing:
532 intptr = &options->afs_token_passing;
536 case sPasswordAuthentication:
537 intptr = &options->password_authentication;
540 case sKbdInteractiveAuthentication:
541 intptr = &options->kbd_interactive_authentication;
545 intptr = &options->check_mail;
548 case sChallengeResponseAuthentication:
549 intptr = &options->challenge_reponse_authentication;
553 intptr = &options->print_motd;
557 intptr = &options->x11_forwarding;
560 case sX11DisplayOffset:
561 intptr = &options->x11_display_offset;
565 charptr = &options->xauth_location;
569 intptr = &options->strict_modes;
573 intptr = &options->keepalives;
577 intptr = &options->permit_empty_passwd;
581 intptr = &options->use_login;
585 intptr = &options->gateway_ports;
588 case sReverseMappingCheck:
589 intptr = &options->reverse_mapping_check;
593 intptr = (int *) &options->log_facility;
595 value = log_facility_number(arg);
596 if (value == (SyslogFacility) - 1)
597 fatal("%.200s line %d: unsupported log facility '%s'\n",
598 filename, linenum, arg ? arg : "<NONE>");
600 *intptr = (SyslogFacility) value;
604 intptr = (int *) &options->log_level;
606 value = log_level_number(arg);
607 if (value == (LogLevel) - 1)
608 fatal("%.200s line %d: unsupported log level '%s'\n",
609 filename, linenum, arg ? arg : "<NONE>");
611 *intptr = (LogLevel) value;
614 case sAllowTcpForwarding:
615 intptr = &options->allow_tcp_forwarding;
619 while ((arg = strdelim(&cp)) && *arg != '\0') {
620 if (options->num_allow_users >= MAX_ALLOW_USERS)
621 fatal("%s line %d: too many allow users.\n",
623 options->allow_users[options->num_allow_users++] = xstrdup(arg);
628 while ((arg = strdelim(&cp)) && *arg != '\0') {
629 if (options->num_deny_users >= MAX_DENY_USERS)
630 fatal( "%s line %d: too many deny users.\n",
632 options->deny_users[options->num_deny_users++] = xstrdup(arg);
637 while ((arg = strdelim(&cp)) && *arg != '\0') {
638 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
639 fatal("%s line %d: too many allow groups.\n",
641 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
646 while ((arg = strdelim(&cp)) && *arg != '\0') {
647 if (options->num_deny_groups >= MAX_DENY_GROUPS)
648 fatal("%s line %d: too many deny groups.\n",
650 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
656 if (!arg || *arg == '\0')
657 fatal("%s line %d: Missing argument.", filename, linenum);
658 if (!ciphers_valid(arg))
659 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
660 filename, linenum, arg ? arg : "<NONE>");
661 if (options->ciphers == NULL)
662 options->ciphers = xstrdup(arg);
667 if (!arg || *arg == '\0')
668 fatal("%s line %d: Missing argument.", filename, linenum);
670 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
671 filename, linenum, arg ? arg : "<NONE>");
672 if (options->macs == NULL)
673 options->macs = xstrdup(arg);
677 intptr = &options->protocol;
679 if (!arg || *arg == '\0')
680 fatal("%s line %d: Missing argument.", filename, linenum);
681 value = proto_spec(arg);
682 if (value == SSH_PROTO_UNKNOWN)
683 fatal("%s line %d: Bad protocol spec '%s'.",
684 filename, linenum, arg ? arg : "<NONE>");
685 if (*intptr == SSH_PROTO_UNKNOWN)
690 if(options->num_subsystems >= MAX_SUBSYSTEMS) {
691 fatal("%s line %d: too many subsystems defined.",
695 if (!arg || *arg == '\0')
696 fatal("%s line %d: Missing subsystem name.",
698 for (i = 0; i < options->num_subsystems; i++)
699 if(strcmp(arg, options->subsystem_name[i]) == 0)
700 fatal("%s line %d: Subsystem '%s' already defined.",
701 filename, linenum, arg);
702 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
704 if (!arg || *arg == '\0')
705 fatal("%s line %d: Missing subsystem command.",
707 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
708 options->num_subsystems++;
713 if (!arg || *arg == '\0')
714 fatal("%s line %d: Missing MaxStartups spec.",
716 if (sscanf(arg, "%d:%d:%d",
717 &options->max_startups_begin,
718 &options->max_startups_rate,
719 &options->max_startups) == 3) {
720 if (options->max_startups_begin >
721 options->max_startups ||
722 options->max_startups_rate > 100 ||
723 options->max_startups_rate < 1)
724 fatal("%s line %d: Illegal MaxStartups spec.",
728 intptr = &options->max_startups;
732 charptr = &options->banner;
736 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
737 filename, linenum, arg, opcode);
740 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
742 "%s line %d: garbage at end of line; \"%.200s\".\n",
743 filename, linenum, arg);
748 if (bad_options > 0) {
749 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
750 filename, bad_options);