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.63 2001/01/22 23:06:39 markus Exp $");
27 #include "pathnames.h"
28 #include "tildexpand.h"
32 /* add listen address */
33 void add_listen_addr(ServerOptions *options, char *addr);
35 /* AF_UNSPEC or AF_INET or AF_INET6 */
38 /* Initializes the server options to their default values. */
41 initialize_server_options(ServerOptions *options)
43 memset(options, 0, sizeof(*options));
44 options->num_ports = 0;
45 options->ports_from_cmdline = 0;
46 options->listen_addrs = NULL;
47 options->num_host_key_files = 0;
48 options->pid_file = NULL;
49 options->server_key_bits = -1;
50 options->login_grace_time = -1;
51 options->key_regeneration_time = -1;
52 options->permit_root_login = -1;
53 options->ignore_rhosts = -1;
54 options->ignore_user_known_hosts = -1;
55 options->print_motd = -1;
56 options->check_mail = -1;
57 options->x11_forwarding = -1;
58 options->x11_display_offset = -1;
59 options->xauth_location = NULL;
60 options->strict_modes = -1;
61 options->keepalives = -1;
62 options->log_facility = (SyslogFacility) - 1;
63 options->log_level = (LogLevel) - 1;
64 options->rhosts_authentication = -1;
65 options->rhosts_rsa_authentication = -1;
66 options->rsa_authentication = -1;
67 options->pubkey_authentication = -1;
69 options->kerberos_authentication = -1;
70 options->kerberos_or_local_passwd = -1;
71 options->kerberos_ticket_cleanup = -1;
74 options->kerberos_tgt_passing = -1;
75 options->afs_token_passing = -1;
77 options->password_authentication = -1;
78 options->kbd_interactive_authentication = -1;
79 options->challenge_reponse_authentication = -1;
80 options->permit_empty_passwd = -1;
81 options->use_login = -1;
82 options->allow_tcp_forwarding = -1;
83 options->num_allow_users = 0;
84 options->num_deny_users = 0;
85 options->num_allow_groups = 0;
86 options->num_deny_groups = 0;
87 options->ciphers = NULL;
88 options->protocol = SSH_PROTO_UNKNOWN;
89 options->gateway_ports = -1;
90 options->num_subsystems = 0;
91 options->max_startups_begin = -1;
92 options->max_startups_rate = -1;
93 options->max_startups = -1;
94 options->banner = NULL;
98 fill_default_server_options(ServerOptions *options)
100 if (options->protocol == SSH_PROTO_UNKNOWN)
101 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
102 if (options->num_host_key_files == 0) {
103 /* fill default hostkeys for protocols */
104 if (options->protocol & SSH_PROTO_1)
105 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE;
106 if (options->protocol & SSH_PROTO_2)
107 options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE;
109 if (options->num_ports == 0)
110 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
111 if (options->listen_addrs == NULL)
112 add_listen_addr(options, NULL);
113 if (options->pid_file == NULL)
114 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
115 if (options->server_key_bits == -1)
116 options->server_key_bits = 768;
117 if (options->login_grace_time == -1)
118 options->login_grace_time = 600;
119 if (options->key_regeneration_time == -1)
120 options->key_regeneration_time = 3600;
121 if (options->permit_root_login == -1)
122 options->permit_root_login = 1; /* yes */
123 if (options->ignore_rhosts == -1)
124 options->ignore_rhosts = 1;
125 if (options->ignore_user_known_hosts == -1)
126 options->ignore_user_known_hosts = 0;
127 if (options->check_mail == -1)
128 options->check_mail = 0;
129 if (options->print_motd == -1)
130 options->print_motd = 1;
131 if (options->x11_forwarding == -1)
132 options->x11_forwarding = 0;
133 if (options->x11_display_offset == -1)
134 options->x11_display_offset = 10;
136 if (options->xauth_location == NULL)
137 options->xauth_location = XAUTH_PATH;
138 #endif /* XAUTH_PATH */
139 if (options->strict_modes == -1)
140 options->strict_modes = 1;
141 if (options->keepalives == -1)
142 options->keepalives = 1;
143 if (options->log_facility == (SyslogFacility) (-1))
144 options->log_facility = SYSLOG_FACILITY_AUTH;
145 if (options->log_level == (LogLevel) (-1))
146 options->log_level = SYSLOG_LEVEL_INFO;
147 if (options->rhosts_authentication == -1)
148 options->rhosts_authentication = 0;
149 if (options->rhosts_rsa_authentication == -1)
150 options->rhosts_rsa_authentication = 0;
151 if (options->rsa_authentication == -1)
152 options->rsa_authentication = 1;
153 if (options->pubkey_authentication == -1)
154 options->pubkey_authentication = 1;
156 if (options->kerberos_authentication == -1)
157 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
158 if (options->kerberos_or_local_passwd == -1)
159 options->kerberos_or_local_passwd = 1;
160 if (options->kerberos_ticket_cleanup == -1)
161 options->kerberos_ticket_cleanup = 1;
164 if (options->kerberos_tgt_passing == -1)
165 options->kerberos_tgt_passing = 0;
166 if (options->afs_token_passing == -1)
167 options->afs_token_passing = k_hasafs();
169 if (options->password_authentication == -1)
170 options->password_authentication = 1;
171 if (options->kbd_interactive_authentication == -1)
172 options->kbd_interactive_authentication = 0;
173 if (options->challenge_reponse_authentication == -1)
174 options->challenge_reponse_authentication = 1;
175 if (options->permit_empty_passwd == -1)
176 options->permit_empty_passwd = 0;
177 if (options->use_login == -1)
178 options->use_login = 0;
179 if (options->allow_tcp_forwarding == -1)
180 options->allow_tcp_forwarding = 1;
181 if (options->gateway_ports == -1)
182 options->gateway_ports = 0;
183 if (options->max_startups == -1)
184 options->max_startups = 10;
185 if (options->max_startups_rate == -1)
186 options->max_startups_rate = 100; /* 100% */
187 if (options->max_startups_begin == -1)
188 options->max_startups_begin = options->max_startups;
191 /* Keyword tokens. */
193 sBadOption, /* == unknown option */
194 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
195 sPermitRootLogin, sLogFacility, sLogLevel,
196 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
198 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
201 sKerberosTgtPassing, sAFSTokenPassing,
203 sChallengeResponseAuthentication,
204 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
205 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
206 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
207 sUseLogin, sAllowTcpForwarding,
208 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
209 sIgnoreUserKnownHosts, sCiphers, sProtocol, sPidFile,
210 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
214 /* Textual representation of the tokens. */
217 ServerOpCodes opcode;
220 { "hostkey", sHostKeyFile },
221 { "hostdsakey", sHostKeyFile }, /* alias */
222 { "pidfile", sPidFile },
223 { "serverkeybits", sServerKeyBits },
224 { "logingracetime", sLoginGraceTime },
225 { "keyregenerationinterval", sKeyRegenerationTime },
226 { "permitrootlogin", sPermitRootLogin },
227 { "syslogfacility", sLogFacility },
228 { "loglevel", sLogLevel },
229 { "rhostsauthentication", sRhostsAuthentication },
230 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
231 { "rsaauthentication", sRSAAuthentication },
232 { "pubkeyauthentication", sPubkeyAuthentication },
233 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
235 { "kerberosauthentication", sKerberosAuthentication },
236 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
237 { "kerberosticketcleanup", sKerberosTicketCleanup },
240 { "kerberostgtpassing", sKerberosTgtPassing },
241 { "afstokenpassing", sAFSTokenPassing },
243 { "passwordauthentication", sPasswordAuthentication },
244 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
245 { "challengeresponseauthentication", sChallengeResponseAuthentication },
246 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
247 { "checkmail", sCheckMail },
248 { "listenaddress", sListenAddress },
249 { "printmotd", sPrintMotd },
250 { "ignorerhosts", sIgnoreRhosts },
251 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
252 { "x11forwarding", sX11Forwarding },
253 { "x11displayoffset", sX11DisplayOffset },
254 { "xauthlocation", sXAuthLocation },
255 { "strictmodes", sStrictModes },
256 { "permitemptypasswords", sEmptyPasswd },
257 { "uselogin", sUseLogin },
258 { "randomseed", sRandomSeedFile },
259 { "keepalive", sKeepAlives },
260 { "allowtcpforwarding", sAllowTcpForwarding },
261 { "allowusers", sAllowUsers },
262 { "denyusers", sDenyUsers },
263 { "allowgroups", sAllowGroups },
264 { "denygroups", sDenyGroups },
265 { "ciphers", sCiphers },
266 { "protocol", sProtocol },
267 { "gatewayports", sGatewayPorts },
268 { "subsystem", sSubsystem },
269 { "maxstartups", sMaxStartups },
270 { "banner", sBanner },
275 * Returns the number of the token pointed to by cp of length len. Never
276 * returns if the token is not known.
280 parse_token(const char *cp, const char *filename,
285 for (i = 0; keywords[i].name; i++)
286 if (strcasecmp(cp, keywords[i].name) == 0)
287 return keywords[i].opcode;
289 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
290 filename, linenum, cp);
298 add_listen_addr(ServerOptions *options, char *addr)
300 struct addrinfo hints, *ai, *aitop;
301 char strport[NI_MAXSERV];
305 if (options->num_ports == 0)
306 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
307 for (i = 0; i < options->num_ports; i++) {
308 memset(&hints, 0, sizeof(hints));
309 hints.ai_family = IPv4or6;
310 hints.ai_socktype = SOCK_STREAM;
311 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
312 snprintf(strport, sizeof strport, "%d", options->ports[i]);
313 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
314 fatal("bad addr or host: %s (%s)\n",
315 addr ? addr : "<NULL>",
316 gai_strerror(gaierr));
317 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
319 ai->ai_next = options->listen_addrs;
320 options->listen_addrs = aitop;
324 /* Reads the server configuration file. */
327 read_server_config(ServerOptions *options, const char *filename)
331 char *cp, **charptr, *arg;
332 int linenum, *intptr, value;
334 ServerOpCodes opcode;
337 f = fopen(filename, "r");
343 while (fgets(line, sizeof(line), f)) {
347 /* Ignore leading whitespace */
350 if (!arg || !*arg || *arg == '#')
354 opcode = parse_token(arg, filename, linenum);
360 /* ignore ports from configfile if cmdline specifies ports */
361 if (options->ports_from_cmdline)
363 if (options->listen_addrs != NULL)
364 fatal("%s line %d: ports must be specified before "
365 "ListenAdress.\n", filename, linenum);
366 if (options->num_ports >= MAX_PORTS)
367 fatal("%s line %d: too many ports.\n",
370 if (!arg || *arg == '\0')
371 fatal("%s line %d: missing port number.\n",
373 options->ports[options->num_ports++] = atoi(arg);
377 intptr = &options->server_key_bits;
380 if (!arg || *arg == '\0') {
381 fprintf(stderr, "%s line %d: missing integer value.\n",
390 case sLoginGraceTime:
391 intptr = &options->login_grace_time;
394 case sKeyRegenerationTime:
395 intptr = &options->key_regeneration_time;
400 if (!arg || *arg == '\0')
401 fatal("%s line %d: missing inet addr.\n",
403 add_listen_addr(options, arg);
407 intptr = &options->num_host_key_files;
408 if (*intptr >= MAX_HOSTKEYS) {
409 fprintf(stderr, "%s line %d: to many host keys specified (max %d).\n",
410 filename, linenum, MAX_HOSTKEYS);
413 charptr = &options->host_key_files[*intptr];
416 if (!arg || *arg == '\0') {
417 fprintf(stderr, "%s line %d: missing file name.\n",
421 if (*charptr == NULL) {
422 *charptr = tilde_expand_filename(arg, getuid());
423 /* increase optional counter */
425 *intptr = *intptr + 1;
430 charptr = &options->pid_file;
433 case sRandomSeedFile:
434 fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
439 case sPermitRootLogin:
440 intptr = &options->permit_root_login;
442 if (!arg || *arg == '\0') {
443 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
447 if (strcmp(arg, "without-password") == 0)
449 else if (strcmp(arg, "yes") == 0)
451 else if (strcmp(arg, "no") == 0)
454 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
455 filename, linenum, arg);
463 intptr = &options->ignore_rhosts;
466 if (!arg || *arg == '\0') {
467 fprintf(stderr, "%s line %d: missing yes/no argument.\n",
471 if (strcmp(arg, "yes") == 0)
473 else if (strcmp(arg, "no") == 0)
476 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
477 filename, linenum, arg);
484 case sIgnoreUserKnownHosts:
485 intptr = &options->ignore_user_known_hosts;
488 case sRhostsAuthentication:
489 intptr = &options->rhosts_authentication;
492 case sRhostsRSAAuthentication:
493 intptr = &options->rhosts_rsa_authentication;
496 case sRSAAuthentication:
497 intptr = &options->rsa_authentication;
500 case sPubkeyAuthentication:
501 intptr = &options->pubkey_authentication;
505 case sKerberosAuthentication:
506 intptr = &options->kerberos_authentication;
509 case sKerberosOrLocalPasswd:
510 intptr = &options->kerberos_or_local_passwd;
513 case sKerberosTicketCleanup:
514 intptr = &options->kerberos_ticket_cleanup;
519 case sKerberosTgtPassing:
520 intptr = &options->kerberos_tgt_passing;
523 case sAFSTokenPassing:
524 intptr = &options->afs_token_passing;
528 case sPasswordAuthentication:
529 intptr = &options->password_authentication;
532 case sKbdInteractiveAuthentication:
533 intptr = &options->kbd_interactive_authentication;
537 intptr = &options->check_mail;
540 case sChallengeResponseAuthentication:
541 intptr = &options->challenge_reponse_authentication;
545 intptr = &options->print_motd;
549 intptr = &options->x11_forwarding;
552 case sX11DisplayOffset:
553 intptr = &options->x11_display_offset;
557 charptr = &options->xauth_location;
561 intptr = &options->strict_modes;
565 intptr = &options->keepalives;
569 intptr = &options->permit_empty_passwd;
573 intptr = &options->use_login;
577 intptr = &options->gateway_ports;
581 intptr = (int *) &options->log_facility;
583 value = log_facility_number(arg);
584 if (value == (SyslogFacility) - 1)
585 fatal("%.200s line %d: unsupported log facility '%s'\n",
586 filename, linenum, arg ? arg : "<NONE>");
588 *intptr = (SyslogFacility) value;
592 intptr = (int *) &options->log_level;
594 value = log_level_number(arg);
595 if (value == (LogLevel) - 1)
596 fatal("%.200s line %d: unsupported log level '%s'\n",
597 filename, linenum, arg ? arg : "<NONE>");
599 *intptr = (LogLevel) value;
602 case sAllowTcpForwarding:
603 intptr = &options->allow_tcp_forwarding;
607 while ((arg = strdelim(&cp)) && *arg != '\0') {
608 if (options->num_allow_users >= MAX_ALLOW_USERS)
609 fatal("%s line %d: too many allow users.\n",
611 options->allow_users[options->num_allow_users++] = xstrdup(arg);
616 while ((arg = strdelim(&cp)) && *arg != '\0') {
617 if (options->num_deny_users >= MAX_DENY_USERS)
618 fatal( "%s line %d: too many deny users.\n",
620 options->deny_users[options->num_deny_users++] = xstrdup(arg);
625 while ((arg = strdelim(&cp)) && *arg != '\0') {
626 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
627 fatal("%s line %d: too many allow groups.\n",
629 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
634 while ((arg = strdelim(&cp)) && *arg != '\0') {
635 if (options->num_deny_groups >= MAX_DENY_GROUPS)
636 fatal("%s line %d: too many deny groups.\n",
638 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
644 if (!arg || *arg == '\0')
645 fatal("%s line %d: Missing argument.", filename, linenum);
646 if (!ciphers_valid(arg))
647 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
648 filename, linenum, arg ? arg : "<NONE>");
649 if (options->ciphers == NULL)
650 options->ciphers = xstrdup(arg);
654 intptr = &options->protocol;
656 if (!arg || *arg == '\0')
657 fatal("%s line %d: Missing argument.", filename, linenum);
658 value = proto_spec(arg);
659 if (value == SSH_PROTO_UNKNOWN)
660 fatal("%s line %d: Bad protocol spec '%s'.",
661 filename, linenum, arg ? arg : "<NONE>");
662 if (*intptr == SSH_PROTO_UNKNOWN)
667 if(options->num_subsystems >= MAX_SUBSYSTEMS) {
668 fatal("%s line %d: too many subsystems defined.",
672 if (!arg || *arg == '\0')
673 fatal("%s line %d: Missing subsystem name.",
675 for (i = 0; i < options->num_subsystems; i++)
676 if(strcmp(arg, options->subsystem_name[i]) == 0)
677 fatal("%s line %d: Subsystem '%s' already defined.",
678 filename, linenum, arg);
679 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
681 if (!arg || *arg == '\0')
682 fatal("%s line %d: Missing subsystem command.",
684 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
685 options->num_subsystems++;
690 if (!arg || *arg == '\0')
691 fatal("%s line %d: Missing MaxStartups spec.",
693 if (sscanf(arg, "%d:%d:%d",
694 &options->max_startups_begin,
695 &options->max_startups_rate,
696 &options->max_startups) == 3) {
697 if (options->max_startups_begin >
698 options->max_startups ||
699 options->max_startups_rate > 100 ||
700 options->max_startups_rate < 1)
701 fatal("%s line %d: Illegal MaxStartups spec.",
705 intptr = &options->max_startups;
709 charptr = &options->banner;
713 fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
714 filename, linenum, arg, opcode);
717 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
719 "%s line %d: garbage at end of line; \"%.200s\".\n",
720 filename, linenum, arg);
725 if (bad_options > 0) {
726 fprintf(stderr, "%s: terminating, %d bad configuration options\n",
727 filename, bad_options);