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.118 2003/04/09 08:23:52 hin Exp $");
24 * XXX: Bodge - but then, so is using the kerberos IV KEYFILE to get a
27 # define KEYFILE "/etc/krb5.keytab"
40 #include "pathnames.h"
41 #include "tildexpand.h"
47 static void add_listen_addr(ServerOptions *, char *, u_short);
48 static void add_one_listen_addr(ServerOptions *, char *, u_short);
50 /* AF_UNSPEC or AF_INET or AF_INET6 */
52 /* Use of privilege separation or not */
53 extern int use_privsep;
55 /* Initializes the server options to their default values. */
58 initialize_server_options(ServerOptions *options)
60 memset(options, 0, sizeof(*options));
63 /* Portable-specific options */
64 options->use_pam = -1;
67 /* Standard Options */
68 options->num_ports = 0;
69 options->ports_from_cmdline = 0;
70 options->listen_addrs = NULL;
71 options->num_host_key_files = 0;
72 options->pid_file = NULL;
73 options->server_key_bits = -1;
74 options->login_grace_time = -1;
75 options->key_regeneration_time = -1;
76 options->permit_root_login = PERMIT_NOT_SET;
77 options->ignore_rhosts = -1;
78 options->ignore_user_known_hosts = -1;
79 options->print_motd = -1;
80 options->print_lastlog = -1;
81 options->x11_forwarding = -1;
82 options->x11_display_offset = -1;
83 options->x11_use_localhost = -1;
84 options->xauth_location = NULL;
85 options->strict_modes = -1;
86 options->keepalives = -1;
87 options->log_facility = SYSLOG_FACILITY_NOT_SET;
88 options->log_level = SYSLOG_LEVEL_NOT_SET;
89 options->rhosts_authentication = -1;
90 options->rhosts_rsa_authentication = -1;
91 options->hostbased_authentication = -1;
92 options->hostbased_uses_name_from_packet_only = -1;
93 options->rsa_authentication = -1;
94 options->pubkey_authentication = -1;
95 #if defined(KRB4) || defined(KRB5)
96 options->kerberos_authentication = -1;
97 options->kerberos_or_local_passwd = -1;
98 options->kerberos_ticket_cleanup = -1;
100 #if defined(AFS) || defined(KRB5)
101 options->kerberos_tgt_passing = -1;
104 options->afs_token_passing = -1;
106 options->password_authentication = -1;
107 options->kbd_interactive_authentication = -1;
108 options->challenge_response_authentication = -1;
109 options->permit_empty_passwd = -1;
110 options->permit_user_env = -1;
111 options->use_login = -1;
112 options->compression = -1;
113 options->allow_tcp_forwarding = -1;
114 options->num_allow_users = 0;
115 options->num_deny_users = 0;
116 options->num_allow_groups = 0;
117 options->num_deny_groups = 0;
118 options->ciphers = NULL;
119 options->macs = NULL;
120 options->protocol = SSH_PROTO_UNKNOWN;
121 options->gateway_ports = -1;
122 options->num_subsystems = 0;
123 options->max_startups_begin = -1;
124 options->max_startups_rate = -1;
125 options->max_startups = -1;
126 options->banner = NULL;
127 options->verify_reverse_mapping = -1;
128 options->client_alive_interval = -1;
129 options->client_alive_count_max = -1;
130 options->authorized_keys_file = NULL;
131 options->authorized_keys_file2 = NULL;
133 /* Needs to be accessable in many places */
138 fill_default_server_options(ServerOptions *options)
140 /* Portable-specific options */
142 if (options->use_pam == -1)
143 options->use_pam = 1;
146 /* Standard Options */
147 if (options->protocol == SSH_PROTO_UNKNOWN)
148 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
149 if (options->num_host_key_files == 0) {
150 /* fill default hostkeys for protocols */
151 if (options->protocol & SSH_PROTO_1)
152 options->host_key_files[options->num_host_key_files++] =
154 if (options->protocol & SSH_PROTO_2) {
155 options->host_key_files[options->num_host_key_files++] =
156 _PATH_HOST_RSA_KEY_FILE;
157 options->host_key_files[options->num_host_key_files++] =
158 _PATH_HOST_DSA_KEY_FILE;
161 if (options->num_ports == 0)
162 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
163 if (options->listen_addrs == NULL)
164 add_listen_addr(options, NULL, 0);
165 if (options->pid_file == NULL)
166 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
167 if (options->server_key_bits == -1)
168 options->server_key_bits = 768;
169 if (options->login_grace_time == -1)
170 options->login_grace_time = 120;
171 if (options->key_regeneration_time == -1)
172 options->key_regeneration_time = 3600;
173 if (options->permit_root_login == PERMIT_NOT_SET)
174 options->permit_root_login = PERMIT_YES;
175 if (options->ignore_rhosts == -1)
176 options->ignore_rhosts = 1;
177 if (options->ignore_user_known_hosts == -1)
178 options->ignore_user_known_hosts = 0;
179 if (options->print_motd == -1)
180 options->print_motd = 1;
181 if (options->print_lastlog == -1)
182 options->print_lastlog = 1;
183 if (options->x11_forwarding == -1)
184 options->x11_forwarding = 0;
185 if (options->x11_display_offset == -1)
186 options->x11_display_offset = 10;
187 if (options->x11_use_localhost == -1)
188 options->x11_use_localhost = 1;
189 if (options->xauth_location == NULL)
190 options->xauth_location = _PATH_XAUTH;
191 if (options->strict_modes == -1)
192 options->strict_modes = 1;
193 if (options->keepalives == -1)
194 options->keepalives = 1;
195 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
196 options->log_facility = SYSLOG_FACILITY_AUTH;
197 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
198 options->log_level = SYSLOG_LEVEL_INFO;
199 if (options->rhosts_authentication == -1)
200 options->rhosts_authentication = 0;
201 if (options->rhosts_rsa_authentication == -1)
202 options->rhosts_rsa_authentication = 0;
203 if (options->hostbased_authentication == -1)
204 options->hostbased_authentication = 0;
205 if (options->hostbased_uses_name_from_packet_only == -1)
206 options->hostbased_uses_name_from_packet_only = 0;
207 if (options->rsa_authentication == -1)
208 options->rsa_authentication = 1;
209 if (options->pubkey_authentication == -1)
210 options->pubkey_authentication = 1;
211 #if defined(KRB4) || defined(KRB5)
212 if (options->kerberos_authentication == -1)
213 options->kerberos_authentication = 0;
214 if (options->kerberos_or_local_passwd == -1)
215 options->kerberos_or_local_passwd = 1;
216 if (options->kerberos_ticket_cleanup == -1)
217 options->kerberos_ticket_cleanup = 1;
219 #if defined(AFS) || defined(KRB5)
220 if (options->kerberos_tgt_passing == -1)
221 options->kerberos_tgt_passing = 0;
224 if (options->afs_token_passing == -1)
225 options->afs_token_passing = 0;
227 if (options->password_authentication == -1)
228 options->password_authentication = 1;
229 if (options->kbd_interactive_authentication == -1)
230 options->kbd_interactive_authentication = 0;
231 if (options->challenge_response_authentication == -1)
232 options->challenge_response_authentication = 1;
233 if (options->permit_empty_passwd == -1)
234 options->permit_empty_passwd = 0;
235 if (options->permit_user_env == -1)
236 options->permit_user_env = 0;
237 if (options->use_login == -1)
238 options->use_login = 0;
239 if (options->compression == -1)
240 options->compression = 1;
241 if (options->allow_tcp_forwarding == -1)
242 options->allow_tcp_forwarding = 1;
243 if (options->gateway_ports == -1)
244 options->gateway_ports = 0;
245 if (options->max_startups == -1)
246 options->max_startups = 10;
247 if (options->max_startups_rate == -1)
248 options->max_startups_rate = 100; /* 100% */
249 if (options->max_startups_begin == -1)
250 options->max_startups_begin = options->max_startups;
251 if (options->verify_reverse_mapping == -1)
252 options->verify_reverse_mapping = 0;
253 if (options->client_alive_interval == -1)
254 options->client_alive_interval = 0;
255 if (options->client_alive_count_max == -1)
256 options->client_alive_count_max = 3;
257 if (options->authorized_keys_file2 == NULL) {
258 /* authorized_keys_file2 falls back to authorized_keys_file */
259 if (options->authorized_keys_file != NULL)
260 options->authorized_keys_file2 = options->authorized_keys_file;
262 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
264 if (options->authorized_keys_file == NULL)
265 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
267 /* Turn privilege separation on by default */
268 if (use_privsep == -1)
272 if (use_privsep && options->compression == 1) {
273 error("This platform does not support both privilege "
274 "separation and compression");
275 error("Compression disabled");
276 options->compression = 0;
282 /* Keyword tokens. */
284 sBadOption, /* == unknown option */
285 /* Portable-specific options */
287 /* Standard Options */
288 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
289 sPermitRootLogin, sLogFacility, sLogLevel,
290 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
291 #if defined(KRB4) || defined(KRB5)
292 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
294 #if defined(AFS) || defined(KRB5)
300 sChallengeResponseAuthentication,
301 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
302 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
303 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
304 sStrictModes, sEmptyPasswd, sKeepAlives,
305 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
306 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
307 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
308 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
309 sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
310 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
311 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
312 sUsePrivilegeSeparation,
316 /* Textual representation of the tokens. */
319 ServerOpCodes opcode;
321 /* Portable-specific options */
322 { "UsePAM", sUsePAM },
323 /* Standard Options */
325 { "hostkey", sHostKeyFile },
326 { "hostdsakey", sHostKeyFile }, /* alias */
327 { "pidfile", sPidFile },
328 { "serverkeybits", sServerKeyBits },
329 { "logingracetime", sLoginGraceTime },
330 { "keyregenerationinterval", sKeyRegenerationTime },
331 { "permitrootlogin", sPermitRootLogin },
332 { "syslogfacility", sLogFacility },
333 { "loglevel", sLogLevel },
334 { "rhostsauthentication", sRhostsAuthentication },
335 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
336 { "hostbasedauthentication", sHostbasedAuthentication },
337 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
338 { "rsaauthentication", sRSAAuthentication },
339 { "pubkeyauthentication", sPubkeyAuthentication },
340 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
341 #if defined(KRB4) || defined(KRB5)
342 { "kerberosauthentication", sKerberosAuthentication },
343 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
344 { "kerberosticketcleanup", sKerberosTicketCleanup },
346 #if defined(AFS) || defined(KRB5)
347 { "kerberostgtpassing", sKerberosTgtPassing },
350 { "afstokenpassing", sAFSTokenPassing },
352 { "passwordauthentication", sPasswordAuthentication },
353 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
354 { "challengeresponseauthentication", sChallengeResponseAuthentication },
355 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
356 { "checkmail", sDeprecated },
357 { "listenaddress", sListenAddress },
358 { "printmotd", sPrintMotd },
359 { "printlastlog", sPrintLastLog },
360 { "ignorerhosts", sIgnoreRhosts },
361 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
362 { "x11forwarding", sX11Forwarding },
363 { "x11displayoffset", sX11DisplayOffset },
364 { "x11uselocalhost", sX11UseLocalhost },
365 { "xauthlocation", sXAuthLocation },
366 { "strictmodes", sStrictModes },
367 { "permitemptypasswords", sEmptyPasswd },
368 { "permituserenvironment", sPermitUserEnvironment },
369 { "uselogin", sUseLogin },
370 { "compression", sCompression },
371 { "keepalive", sKeepAlives },
372 { "allowtcpforwarding", sAllowTcpForwarding },
373 { "allowusers", sAllowUsers },
374 { "denyusers", sDenyUsers },
375 { "allowgroups", sAllowGroups },
376 { "denygroups", sDenyGroups },
377 { "ciphers", sCiphers },
379 { "protocol", sProtocol },
380 { "gatewayports", sGatewayPorts },
381 { "subsystem", sSubsystem },
382 { "maxstartups", sMaxStartups },
383 { "banner", sBanner },
384 { "verifyreversemapping", sVerifyReverseMapping },
385 { "reversemappingcheck", sVerifyReverseMapping },
386 { "clientaliveinterval", sClientAliveInterval },
387 { "clientalivecountmax", sClientAliveCountMax },
388 { "authorizedkeysfile", sAuthorizedKeysFile },
389 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
390 { "useprivilegeseparation", sUsePrivilegeSeparation},
395 * Returns the number of the token pointed to by cp or sBadOption.
399 parse_token(const char *cp, const char *filename,
404 for (i = 0; keywords[i].name; i++)
405 if (strcasecmp(cp, keywords[i].name) == 0)
406 return keywords[i].opcode;
408 error("%s: line %d: Bad configuration option: %s",
409 filename, linenum, cp);
414 add_listen_addr(ServerOptions *options, char *addr, u_short port)
418 if (options->num_ports == 0)
419 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
421 for (i = 0; i < options->num_ports; i++)
422 add_one_listen_addr(options, addr, options->ports[i]);
424 add_one_listen_addr(options, addr, port);
428 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
430 struct addrinfo hints, *ai, *aitop;
431 char strport[NI_MAXSERV];
434 memset(&hints, 0, sizeof(hints));
435 hints.ai_family = IPv4or6;
436 hints.ai_socktype = SOCK_STREAM;
437 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
438 snprintf(strport, sizeof strport, "%u", port);
439 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
440 fatal("bad addr or host: %s (%s)",
441 addr ? addr : "<NULL>",
442 gai_strerror(gaierr));
443 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
445 ai->ai_next = options->listen_addrs;
446 options->listen_addrs = aitop;
450 process_server_config_line(ServerOptions *options, char *line,
451 const char *filename, int linenum)
453 char *cp, **charptr, *arg, *p;
454 int *intptr, value, i, n;
455 ServerOpCodes opcode;
459 /* Ignore leading whitespace */
462 if (!arg || !*arg || *arg == '#')
466 opcode = parse_token(arg, filename, linenum);
468 /* Portable-specific options */
470 intptr = &options->use_pam;
473 /* Standard Options */
477 /* ignore ports from configfile if cmdline specifies ports */
478 if (options->ports_from_cmdline)
480 if (options->listen_addrs != NULL)
481 fatal("%s line %d: ports must be specified before "
482 "ListenAddress.", filename, linenum);
483 if (options->num_ports >= MAX_PORTS)
484 fatal("%s line %d: too many ports.",
487 if (!arg || *arg == '\0')
488 fatal("%s line %d: missing port number.",
490 options->ports[options->num_ports++] = a2port(arg);
491 if (options->ports[options->num_ports-1] == 0)
492 fatal("%s line %d: Badly formatted port number.",
497 intptr = &options->server_key_bits;
500 if (!arg || *arg == '\0')
501 fatal("%s line %d: missing integer value.",
508 case sLoginGraceTime:
509 intptr = &options->login_grace_time;
512 if (!arg || *arg == '\0')
513 fatal("%s line %d: missing time value.",
515 if ((value = convtime(arg)) == -1)
516 fatal("%s line %d: invalid time value.",
522 case sKeyRegenerationTime:
523 intptr = &options->key_regeneration_time;
528 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
529 fatal("%s line %d: missing inet addr.",
532 if ((p = strchr(arg, ']')) == NULL)
533 fatal("%s line %d: bad ipv6 inet addr usage.",
536 memmove(p, p+1, strlen(p+1)+1);
537 } else if (((p = strchr(arg, ':')) == NULL) ||
538 (strchr(p+1, ':') != NULL)) {
539 add_listen_addr(options, arg, 0);
547 fatal("%s line %d: bad inet addr:port usage.",
551 if ((port = a2port(p)) == 0)
552 fatal("%s line %d: bad port number.",
554 add_listen_addr(options, arg, port);
556 } else if (*p == '\0')
557 add_listen_addr(options, arg, 0);
559 fatal("%s line %d: bad inet addr usage.",
564 intptr = &options->num_host_key_files;
565 if (*intptr >= MAX_HOSTKEYS)
566 fatal("%s line %d: too many host keys specified (max %d).",
567 filename, linenum, MAX_HOSTKEYS);
568 charptr = &options->host_key_files[*intptr];
571 if (!arg || *arg == '\0')
572 fatal("%s line %d: missing file name.",
574 if (*charptr == NULL) {
575 *charptr = tilde_expand_filename(arg, getuid());
576 /* increase optional counter */
578 *intptr = *intptr + 1;
583 charptr = &options->pid_file;
586 case sPermitRootLogin:
587 intptr = &options->permit_root_login;
589 if (!arg || *arg == '\0')
590 fatal("%s line %d: missing yes/"
591 "without-password/forced-commands-only/no "
592 "argument.", filename, linenum);
593 value = 0; /* silence compiler */
594 if (strcmp(arg, "without-password") == 0)
595 value = PERMIT_NO_PASSWD;
596 else if (strcmp(arg, "forced-commands-only") == 0)
597 value = PERMIT_FORCED_ONLY;
598 else if (strcmp(arg, "yes") == 0)
600 else if (strcmp(arg, "no") == 0)
603 fatal("%s line %d: Bad yes/"
604 "without-password/forced-commands-only/no "
605 "argument: %s", filename, linenum, arg);
611 intptr = &options->ignore_rhosts;
614 if (!arg || *arg == '\0')
615 fatal("%s line %d: missing yes/no argument.",
617 value = 0; /* silence compiler */
618 if (strcmp(arg, "yes") == 0)
620 else if (strcmp(arg, "no") == 0)
623 fatal("%s line %d: Bad yes/no argument: %s",
624 filename, linenum, arg);
629 case sIgnoreUserKnownHosts:
630 intptr = &options->ignore_user_known_hosts;
633 case sRhostsAuthentication:
634 intptr = &options->rhosts_authentication;
637 case sRhostsRSAAuthentication:
638 intptr = &options->rhosts_rsa_authentication;
641 case sHostbasedAuthentication:
642 intptr = &options->hostbased_authentication;
645 case sHostbasedUsesNameFromPacketOnly:
646 intptr = &options->hostbased_uses_name_from_packet_only;
649 case sRSAAuthentication:
650 intptr = &options->rsa_authentication;
653 case sPubkeyAuthentication:
654 intptr = &options->pubkey_authentication;
656 #if defined(KRB4) || defined(KRB5)
657 case sKerberosAuthentication:
658 intptr = &options->kerberos_authentication;
661 case sKerberosOrLocalPasswd:
662 intptr = &options->kerberos_or_local_passwd;
665 case sKerberosTicketCleanup:
666 intptr = &options->kerberos_ticket_cleanup;
669 #if defined(AFS) || defined(KRB5)
670 case sKerberosTgtPassing:
671 intptr = &options->kerberos_tgt_passing;
675 case sAFSTokenPassing:
676 intptr = &options->afs_token_passing;
680 case sPasswordAuthentication:
681 intptr = &options->password_authentication;
684 case sKbdInteractiveAuthentication:
685 intptr = &options->kbd_interactive_authentication;
688 case sChallengeResponseAuthentication:
689 intptr = &options->challenge_response_authentication;
693 intptr = &options->print_motd;
697 intptr = &options->print_lastlog;
701 intptr = &options->x11_forwarding;
704 case sX11DisplayOffset:
705 intptr = &options->x11_display_offset;
708 case sX11UseLocalhost:
709 intptr = &options->x11_use_localhost;
713 charptr = &options->xauth_location;
717 intptr = &options->strict_modes;
721 intptr = &options->keepalives;
725 intptr = &options->permit_empty_passwd;
728 case sPermitUserEnvironment:
729 intptr = &options->permit_user_env;
733 intptr = &options->use_login;
737 intptr = &options->compression;
741 intptr = &options->gateway_ports;
744 case sVerifyReverseMapping:
745 intptr = &options->verify_reverse_mapping;
749 intptr = (int *) &options->log_facility;
751 value = log_facility_number(arg);
752 if (value == SYSLOG_FACILITY_NOT_SET)
753 fatal("%.200s line %d: unsupported log facility '%s'",
754 filename, linenum, arg ? arg : "<NONE>");
756 *intptr = (SyslogFacility) value;
760 intptr = (int *) &options->log_level;
762 value = log_level_number(arg);
763 if (value == SYSLOG_LEVEL_NOT_SET)
764 fatal("%.200s line %d: unsupported log level '%s'",
765 filename, linenum, arg ? arg : "<NONE>");
767 *intptr = (LogLevel) value;
770 case sAllowTcpForwarding:
771 intptr = &options->allow_tcp_forwarding;
774 case sUsePrivilegeSeparation:
775 intptr = &use_privsep;
779 while ((arg = strdelim(&cp)) && *arg != '\0') {
780 if (options->num_allow_users >= MAX_ALLOW_USERS)
781 fatal("%s line %d: too many allow users.",
783 options->allow_users[options->num_allow_users++] =
789 while ((arg = strdelim(&cp)) && *arg != '\0') {
790 if (options->num_deny_users >= MAX_DENY_USERS)
791 fatal( "%s line %d: too many deny users.",
793 options->deny_users[options->num_deny_users++] =
799 while ((arg = strdelim(&cp)) && *arg != '\0') {
800 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
801 fatal("%s line %d: too many allow groups.",
803 options->allow_groups[options->num_allow_groups++] =
809 while ((arg = strdelim(&cp)) && *arg != '\0') {
810 if (options->num_deny_groups >= MAX_DENY_GROUPS)
811 fatal("%s line %d: too many deny groups.",
813 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
819 if (!arg || *arg == '\0')
820 fatal("%s line %d: Missing argument.", filename, linenum);
821 if (!ciphers_valid(arg))
822 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
823 filename, linenum, arg ? arg : "<NONE>");
824 if (options->ciphers == NULL)
825 options->ciphers = xstrdup(arg);
830 if (!arg || *arg == '\0')
831 fatal("%s line %d: Missing argument.", filename, linenum);
833 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
834 filename, linenum, arg ? arg : "<NONE>");
835 if (options->macs == NULL)
836 options->macs = xstrdup(arg);
840 intptr = &options->protocol;
842 if (!arg || *arg == '\0')
843 fatal("%s line %d: Missing argument.", filename, linenum);
844 value = proto_spec(arg);
845 if (value == SSH_PROTO_UNKNOWN)
846 fatal("%s line %d: Bad protocol spec '%s'.",
847 filename, linenum, arg ? arg : "<NONE>");
848 if (*intptr == SSH_PROTO_UNKNOWN)
853 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
854 fatal("%s line %d: too many subsystems defined.",
858 if (!arg || *arg == '\0')
859 fatal("%s line %d: Missing subsystem name.",
861 for (i = 0; i < options->num_subsystems; i++)
862 if (strcmp(arg, options->subsystem_name[i]) == 0)
863 fatal("%s line %d: Subsystem '%s' already defined.",
864 filename, linenum, arg);
865 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
867 if (!arg || *arg == '\0')
868 fatal("%s line %d: Missing subsystem command.",
870 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
871 options->num_subsystems++;
876 if (!arg || *arg == '\0')
877 fatal("%s line %d: Missing MaxStartups spec.",
879 if ((n = sscanf(arg, "%d:%d:%d",
880 &options->max_startups_begin,
881 &options->max_startups_rate,
882 &options->max_startups)) == 3) {
883 if (options->max_startups_begin >
884 options->max_startups ||
885 options->max_startups_rate > 100 ||
886 options->max_startups_rate < 1)
887 fatal("%s line %d: Illegal MaxStartups spec.",
890 fatal("%s line %d: Illegal MaxStartups spec.",
893 options->max_startups = options->max_startups_begin;
897 charptr = &options->banner;
900 * These options can contain %X options expanded at
901 * connect time, so that you can specify paths like:
903 * AuthorizedKeysFile /etc/ssh_keys/%u
905 case sAuthorizedKeysFile:
906 case sAuthorizedKeysFile2:
907 charptr = (opcode == sAuthorizedKeysFile ) ?
908 &options->authorized_keys_file :
909 &options->authorized_keys_file2;
912 case sClientAliveInterval:
913 intptr = &options->client_alive_interval;
916 case sClientAliveCountMax:
917 intptr = &options->client_alive_count_max;
921 logit("%s line %d: Deprecated option %s",
922 filename, linenum, arg);
928 fatal("%s line %d: Missing handler for opcode %s (%d)",
929 filename, linenum, arg, opcode);
931 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
932 fatal("%s line %d: garbage at end of line; \"%.200s\".",
933 filename, linenum, arg);
937 /* Reads the server configuration file. */
940 read_server_config(ServerOptions *options, const char *filename)
942 int linenum, bad_options = 0;
946 debug2("read_server_config: filename %s", filename);
947 f = fopen(filename, "r");
953 while (fgets(line, sizeof(line), f)) {
954 /* Update line number counter. */
956 if (process_server_config_line(options, line, filename, linenum) != 0)
961 fatal("%s: terminating, %d bad configuration options",
962 filename, bad_options);