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.122 2003/06/02 09:17:34 markus 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));
62 /* Portable-specific options */
63 options->use_pam = -1;
65 /* Standard Options */
66 options->num_ports = 0;
67 options->ports_from_cmdline = 0;
68 options->listen_addrs = NULL;
69 options->num_host_key_files = 0;
70 options->pid_file = NULL;
71 options->server_key_bits = -1;
72 options->login_grace_time = -1;
73 options->key_regeneration_time = -1;
74 options->permit_root_login = PERMIT_NOT_SET;
75 options->ignore_rhosts = -1;
76 options->ignore_user_known_hosts = -1;
77 options->print_motd = -1;
78 options->print_lastlog = -1;
79 options->x11_forwarding = -1;
80 options->x11_display_offset = -1;
81 options->x11_use_localhost = -1;
82 options->xauth_location = NULL;
83 options->strict_modes = -1;
84 options->keepalives = -1;
85 options->log_facility = SYSLOG_FACILITY_NOT_SET;
86 options->log_level = SYSLOG_LEVEL_NOT_SET;
87 options->rhosts_authentication = -1;
88 options->rhosts_rsa_authentication = -1;
89 options->hostbased_authentication = -1;
90 options->hostbased_uses_name_from_packet_only = -1;
91 options->rsa_authentication = -1;
92 options->pubkey_authentication = -1;
93 options->kerberos_authentication = -1;
94 options->kerberos_or_local_passwd = -1;
95 options->kerberos_ticket_cleanup = -1;
96 options->kerberos_tgt_passing = -1;
97 options->afs_token_passing = -1;
98 options->password_authentication = -1;
99 options->kbd_interactive_authentication = -1;
100 options->challenge_response_authentication = -1;
101 options->permit_empty_passwd = -1;
102 options->permit_user_env = -1;
103 options->use_login = -1;
104 options->compression = -1;
105 options->allow_tcp_forwarding = -1;
106 options->num_allow_users = 0;
107 options->num_deny_users = 0;
108 options->num_allow_groups = 0;
109 options->num_deny_groups = 0;
110 options->ciphers = NULL;
111 options->macs = NULL;
112 options->protocol = SSH_PROTO_UNKNOWN;
113 options->gateway_ports = -1;
114 options->num_subsystems = 0;
115 options->max_startups_begin = -1;
116 options->max_startups_rate = -1;
117 options->max_startups = -1;
118 options->banner = NULL;
119 options->use_dns = -1;
120 options->client_alive_interval = -1;
121 options->client_alive_count_max = -1;
122 options->authorized_keys_file = NULL;
123 options->authorized_keys_file2 = NULL;
125 /* Needs to be accessable in many places */
130 fill_default_server_options(ServerOptions *options)
132 /* Portable-specific options */
133 if (options->use_pam == -1)
134 options->use_pam = 1;
136 /* Standard Options */
137 if (options->protocol == SSH_PROTO_UNKNOWN)
138 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
139 if (options->num_host_key_files == 0) {
140 /* fill default hostkeys for protocols */
141 if (options->protocol & SSH_PROTO_1)
142 options->host_key_files[options->num_host_key_files++] =
144 if (options->protocol & SSH_PROTO_2) {
145 options->host_key_files[options->num_host_key_files++] =
146 _PATH_HOST_RSA_KEY_FILE;
147 options->host_key_files[options->num_host_key_files++] =
148 _PATH_HOST_DSA_KEY_FILE;
151 if (options->num_ports == 0)
152 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
153 if (options->listen_addrs == NULL)
154 add_listen_addr(options, NULL, 0);
155 if (options->pid_file == NULL)
156 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
157 if (options->server_key_bits == -1)
158 options->server_key_bits = 768;
159 if (options->login_grace_time == -1)
160 options->login_grace_time = 120;
161 if (options->key_regeneration_time == -1)
162 options->key_regeneration_time = 3600;
163 if (options->permit_root_login == PERMIT_NOT_SET)
164 options->permit_root_login = PERMIT_YES;
165 if (options->ignore_rhosts == -1)
166 options->ignore_rhosts = 1;
167 if (options->ignore_user_known_hosts == -1)
168 options->ignore_user_known_hosts = 0;
169 if (options->print_motd == -1)
170 options->print_motd = 1;
171 if (options->print_lastlog == -1)
172 options->print_lastlog = 1;
173 if (options->x11_forwarding == -1)
174 options->x11_forwarding = 0;
175 if (options->x11_display_offset == -1)
176 options->x11_display_offset = 10;
177 if (options->x11_use_localhost == -1)
178 options->x11_use_localhost = 1;
179 if (options->xauth_location == NULL)
180 options->xauth_location = _PATH_XAUTH;
181 if (options->strict_modes == -1)
182 options->strict_modes = 1;
183 if (options->keepalives == -1)
184 options->keepalives = 1;
185 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
186 options->log_facility = SYSLOG_FACILITY_AUTH;
187 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
188 options->log_level = SYSLOG_LEVEL_INFO;
189 if (options->rhosts_authentication == -1)
190 options->rhosts_authentication = 0;
191 if (options->rhosts_rsa_authentication == -1)
192 options->rhosts_rsa_authentication = 0;
193 if (options->hostbased_authentication == -1)
194 options->hostbased_authentication = 0;
195 if (options->hostbased_uses_name_from_packet_only == -1)
196 options->hostbased_uses_name_from_packet_only = 0;
197 if (options->rsa_authentication == -1)
198 options->rsa_authentication = 1;
199 if (options->pubkey_authentication == -1)
200 options->pubkey_authentication = 1;
201 if (options->kerberos_authentication == -1)
202 options->kerberos_authentication = 0;
203 if (options->kerberos_or_local_passwd == -1)
204 options->kerberos_or_local_passwd = 1;
205 if (options->kerberos_ticket_cleanup == -1)
206 options->kerberos_ticket_cleanup = 1;
207 if (options->kerberos_tgt_passing == -1)
208 options->kerberos_tgt_passing = 0;
209 if (options->afs_token_passing == -1)
210 options->afs_token_passing = 0;
211 if (options->password_authentication == -1)
212 options->password_authentication = 1;
213 if (options->kbd_interactive_authentication == -1)
214 options->kbd_interactive_authentication = 0;
215 if (options->challenge_response_authentication == -1)
216 options->challenge_response_authentication = 1;
217 if (options->permit_empty_passwd == -1)
218 options->permit_empty_passwd = 0;
219 if (options->permit_user_env == -1)
220 options->permit_user_env = 0;
221 if (options->use_login == -1)
222 options->use_login = 0;
223 if (options->compression == -1)
224 options->compression = 1;
225 if (options->allow_tcp_forwarding == -1)
226 options->allow_tcp_forwarding = 1;
227 if (options->gateway_ports == -1)
228 options->gateway_ports = 0;
229 if (options->max_startups == -1)
230 options->max_startups = 10;
231 if (options->max_startups_rate == -1)
232 options->max_startups_rate = 100; /* 100% */
233 if (options->max_startups_begin == -1)
234 options->max_startups_begin = options->max_startups;
235 if (options->use_dns == -1)
236 options->use_dns = 1;
237 if (options->client_alive_interval == -1)
238 options->client_alive_interval = 0;
239 if (options->client_alive_count_max == -1)
240 options->client_alive_count_max = 3;
241 if (options->authorized_keys_file2 == NULL) {
242 /* authorized_keys_file2 falls back to authorized_keys_file */
243 if (options->authorized_keys_file != NULL)
244 options->authorized_keys_file2 = options->authorized_keys_file;
246 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
248 if (options->authorized_keys_file == NULL)
249 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
251 /* Turn privilege separation on by default */
252 if (use_privsep == -1)
256 if (use_privsep && options->compression == 1) {
257 error("This platform does not support both privilege "
258 "separation and compression");
259 error("Compression disabled");
260 options->compression = 0;
266 /* Keyword tokens. */
268 sBadOption, /* == unknown option */
269 /* Portable-specific options */
271 /* Standard Options */
272 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
273 sPermitRootLogin, sLogFacility, sLogLevel,
274 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
275 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
276 sKerberosTgtPassing, sAFSTokenPassing, sChallengeResponseAuthentication,
277 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
278 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
279 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
280 sStrictModes, sEmptyPasswd, sKeepAlives,
281 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
282 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
283 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
284 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
285 sBanner, sUseDNS, sHostbasedAuthentication,
286 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
287 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
288 sUsePrivilegeSeparation,
289 sDeprecated, sUnsupported
292 /* Textual representation of the tokens. */
295 ServerOpCodes opcode;
297 /* Portable-specific options */
299 { "UsePAM", sUsePAM },
301 { "UsePAM", sUnsupported },
303 /* Standard Options */
305 { "hostkey", sHostKeyFile },
306 { "hostdsakey", sHostKeyFile }, /* alias */
307 { "pidfile", sPidFile },
308 { "serverkeybits", sServerKeyBits },
309 { "logingracetime", sLoginGraceTime },
310 { "keyregenerationinterval", sKeyRegenerationTime },
311 { "permitrootlogin", sPermitRootLogin },
312 { "syslogfacility", sLogFacility },
313 { "loglevel", sLogLevel },
314 { "rhostsauthentication", sRhostsAuthentication },
315 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
316 { "hostbasedauthentication", sHostbasedAuthentication },
317 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
318 { "rsaauthentication", sRSAAuthentication },
319 { "pubkeyauthentication", sPubkeyAuthentication },
320 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
321 #if defined(KRB4) || defined(KRB5)
322 { "kerberosauthentication", sKerberosAuthentication },
323 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
324 { "kerberosticketcleanup", sKerberosTicketCleanup },
325 { "kerberostgtpassing", sKerberosTgtPassing },
327 { "kerberosauthentication", sUnsupported },
328 { "kerberosorlocalpasswd", sUnsupported },
329 { "kerberosticketcleanup", sUnsupported },
330 { "kerberostgtpassing", sUnsupported },
333 { "afstokenpassing", sAFSTokenPassing },
335 { "afstokenpassing", sUnsupported },
337 { "passwordauthentication", sPasswordAuthentication },
338 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
339 { "challengeresponseauthentication", sChallengeResponseAuthentication },
340 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
341 { "checkmail", sDeprecated },
342 { "listenaddress", sListenAddress },
343 { "printmotd", sPrintMotd },
344 { "printlastlog", sPrintLastLog },
345 { "ignorerhosts", sIgnoreRhosts },
346 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
347 { "x11forwarding", sX11Forwarding },
348 { "x11displayoffset", sX11DisplayOffset },
349 { "x11uselocalhost", sX11UseLocalhost },
350 { "xauthlocation", sXAuthLocation },
351 { "strictmodes", sStrictModes },
352 { "permitemptypasswords", sEmptyPasswd },
353 { "permituserenvironment", sPermitUserEnvironment },
354 { "uselogin", sUseLogin },
355 { "compression", sCompression },
356 { "keepalive", sKeepAlives },
357 { "allowtcpforwarding", sAllowTcpForwarding },
358 { "allowusers", sAllowUsers },
359 { "denyusers", sDenyUsers },
360 { "allowgroups", sAllowGroups },
361 { "denygroups", sDenyGroups },
362 { "ciphers", sCiphers },
364 { "protocol", sProtocol },
365 { "gatewayports", sGatewayPorts },
366 { "subsystem", sSubsystem },
367 { "maxstartups", sMaxStartups },
368 { "banner", sBanner },
369 { "usedns", sUseDNS },
370 { "verifyreversemapping", sDeprecated },
371 { "reversemappingcheck", sDeprecated },
372 { "clientaliveinterval", sClientAliveInterval },
373 { "clientalivecountmax", sClientAliveCountMax },
374 { "authorizedkeysfile", sAuthorizedKeysFile },
375 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
376 { "useprivilegeseparation", sUsePrivilegeSeparation},
381 * Returns the number of the token pointed to by cp or sBadOption.
385 parse_token(const char *cp, const char *filename,
390 for (i = 0; keywords[i].name; i++)
391 if (strcasecmp(cp, keywords[i].name) == 0)
392 return keywords[i].opcode;
394 error("%s: line %d: Bad configuration option: %s",
395 filename, linenum, cp);
400 add_listen_addr(ServerOptions *options, char *addr, u_short port)
404 if (options->num_ports == 0)
405 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
407 for (i = 0; i < options->num_ports; i++)
408 add_one_listen_addr(options, addr, options->ports[i]);
410 add_one_listen_addr(options, addr, port);
414 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
416 struct addrinfo hints, *ai, *aitop;
417 char strport[NI_MAXSERV];
420 memset(&hints, 0, sizeof(hints));
421 hints.ai_family = IPv4or6;
422 hints.ai_socktype = SOCK_STREAM;
423 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
424 snprintf(strport, sizeof strport, "%u", port);
425 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
426 fatal("bad addr or host: %s (%s)",
427 addr ? addr : "<NULL>",
428 gai_strerror(gaierr));
429 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
431 ai->ai_next = options->listen_addrs;
432 options->listen_addrs = aitop;
436 process_server_config_line(ServerOptions *options, char *line,
437 const char *filename, int linenum)
439 char *cp, **charptr, *arg, *p;
440 int *intptr, value, i, n;
441 ServerOpCodes opcode;
445 /* Ignore leading whitespace */
448 if (!arg || !*arg || *arg == '#')
452 opcode = parse_token(arg, filename, linenum);
454 /* Portable-specific options */
456 intptr = &options->use_pam;
459 /* Standard Options */
463 /* ignore ports from configfile if cmdline specifies ports */
464 if (options->ports_from_cmdline)
466 if (options->listen_addrs != NULL)
467 fatal("%s line %d: ports must be specified before "
468 "ListenAddress.", filename, linenum);
469 if (options->num_ports >= MAX_PORTS)
470 fatal("%s line %d: too many ports.",
473 if (!arg || *arg == '\0')
474 fatal("%s line %d: missing port number.",
476 options->ports[options->num_ports++] = a2port(arg);
477 if (options->ports[options->num_ports-1] == 0)
478 fatal("%s line %d: Badly formatted port number.",
483 intptr = &options->server_key_bits;
486 if (!arg || *arg == '\0')
487 fatal("%s line %d: missing integer value.",
494 case sLoginGraceTime:
495 intptr = &options->login_grace_time;
498 if (!arg || *arg == '\0')
499 fatal("%s line %d: missing time value.",
501 if ((value = convtime(arg)) == -1)
502 fatal("%s line %d: invalid time value.",
508 case sKeyRegenerationTime:
509 intptr = &options->key_regeneration_time;
514 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
515 fatal("%s line %d: missing inet addr.",
518 if ((p = strchr(arg, ']')) == NULL)
519 fatal("%s line %d: bad ipv6 inet addr usage.",
522 memmove(p, p+1, strlen(p+1)+1);
523 } else if (((p = strchr(arg, ':')) == NULL) ||
524 (strchr(p+1, ':') != NULL)) {
525 add_listen_addr(options, arg, 0);
533 fatal("%s line %d: bad inet addr:port usage.",
537 if ((port = a2port(p)) == 0)
538 fatal("%s line %d: bad port number.",
540 add_listen_addr(options, arg, port);
542 } else if (*p == '\0')
543 add_listen_addr(options, arg, 0);
545 fatal("%s line %d: bad inet addr usage.",
550 intptr = &options->num_host_key_files;
551 if (*intptr >= MAX_HOSTKEYS)
552 fatal("%s line %d: too many host keys specified (max %d).",
553 filename, linenum, MAX_HOSTKEYS);
554 charptr = &options->host_key_files[*intptr];
557 if (!arg || *arg == '\0')
558 fatal("%s line %d: missing file name.",
560 if (*charptr == NULL) {
561 *charptr = tilde_expand_filename(arg, getuid());
562 /* increase optional counter */
564 *intptr = *intptr + 1;
569 charptr = &options->pid_file;
572 case sPermitRootLogin:
573 intptr = &options->permit_root_login;
575 if (!arg || *arg == '\0')
576 fatal("%s line %d: missing yes/"
577 "without-password/forced-commands-only/no "
578 "argument.", filename, linenum);
579 value = 0; /* silence compiler */
580 if (strcmp(arg, "without-password") == 0)
581 value = PERMIT_NO_PASSWD;
582 else if (strcmp(arg, "forced-commands-only") == 0)
583 value = PERMIT_FORCED_ONLY;
584 else if (strcmp(arg, "yes") == 0)
586 else if (strcmp(arg, "no") == 0)
589 fatal("%s line %d: Bad yes/"
590 "without-password/forced-commands-only/no "
591 "argument: %s", filename, linenum, arg);
597 intptr = &options->ignore_rhosts;
600 if (!arg || *arg == '\0')
601 fatal("%s line %d: missing yes/no argument.",
603 value = 0; /* silence compiler */
604 if (strcmp(arg, "yes") == 0)
606 else if (strcmp(arg, "no") == 0)
609 fatal("%s line %d: Bad yes/no argument: %s",
610 filename, linenum, arg);
615 case sIgnoreUserKnownHosts:
616 intptr = &options->ignore_user_known_hosts;
619 case sRhostsAuthentication:
620 intptr = &options->rhosts_authentication;
623 case sRhostsRSAAuthentication:
624 intptr = &options->rhosts_rsa_authentication;
627 case sHostbasedAuthentication:
628 intptr = &options->hostbased_authentication;
631 case sHostbasedUsesNameFromPacketOnly:
632 intptr = &options->hostbased_uses_name_from_packet_only;
635 case sRSAAuthentication:
636 intptr = &options->rsa_authentication;
639 case sPubkeyAuthentication:
640 intptr = &options->pubkey_authentication;
643 case sKerberosAuthentication:
644 intptr = &options->kerberos_authentication;
647 case sKerberosOrLocalPasswd:
648 intptr = &options->kerberos_or_local_passwd;
651 case sKerberosTicketCleanup:
652 intptr = &options->kerberos_ticket_cleanup;
655 case sKerberosTgtPassing:
656 intptr = &options->kerberos_tgt_passing;
659 case sAFSTokenPassing:
660 intptr = &options->afs_token_passing;
663 case sPasswordAuthentication:
664 intptr = &options->password_authentication;
667 case sKbdInteractiveAuthentication:
668 intptr = &options->kbd_interactive_authentication;
671 case sChallengeResponseAuthentication:
672 intptr = &options->challenge_response_authentication;
676 intptr = &options->print_motd;
680 intptr = &options->print_lastlog;
684 intptr = &options->x11_forwarding;
687 case sX11DisplayOffset:
688 intptr = &options->x11_display_offset;
691 case sX11UseLocalhost:
692 intptr = &options->x11_use_localhost;
696 charptr = &options->xauth_location;
700 intptr = &options->strict_modes;
704 intptr = &options->keepalives;
708 intptr = &options->permit_empty_passwd;
711 case sPermitUserEnvironment:
712 intptr = &options->permit_user_env;
716 intptr = &options->use_login;
720 intptr = &options->compression;
724 intptr = &options->gateway_ports;
728 intptr = &options->use_dns;
732 intptr = (int *) &options->log_facility;
734 value = log_facility_number(arg);
735 if (value == SYSLOG_FACILITY_NOT_SET)
736 fatal("%.200s line %d: unsupported log facility '%s'",
737 filename, linenum, arg ? arg : "<NONE>");
739 *intptr = (SyslogFacility) value;
743 intptr = (int *) &options->log_level;
745 value = log_level_number(arg);
746 if (value == SYSLOG_LEVEL_NOT_SET)
747 fatal("%.200s line %d: unsupported log level '%s'",
748 filename, linenum, arg ? arg : "<NONE>");
750 *intptr = (LogLevel) value;
753 case sAllowTcpForwarding:
754 intptr = &options->allow_tcp_forwarding;
757 case sUsePrivilegeSeparation:
758 intptr = &use_privsep;
762 while ((arg = strdelim(&cp)) && *arg != '\0') {
763 if (options->num_allow_users >= MAX_ALLOW_USERS)
764 fatal("%s line %d: too many allow users.",
766 options->allow_users[options->num_allow_users++] =
772 while ((arg = strdelim(&cp)) && *arg != '\0') {
773 if (options->num_deny_users >= MAX_DENY_USERS)
774 fatal( "%s line %d: too many deny users.",
776 options->deny_users[options->num_deny_users++] =
782 while ((arg = strdelim(&cp)) && *arg != '\0') {
783 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
784 fatal("%s line %d: too many allow groups.",
786 options->allow_groups[options->num_allow_groups++] =
792 while ((arg = strdelim(&cp)) && *arg != '\0') {
793 if (options->num_deny_groups >= MAX_DENY_GROUPS)
794 fatal("%s line %d: too many deny groups.",
796 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
802 if (!arg || *arg == '\0')
803 fatal("%s line %d: Missing argument.", filename, linenum);
804 if (!ciphers_valid(arg))
805 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
806 filename, linenum, arg ? arg : "<NONE>");
807 if (options->ciphers == NULL)
808 options->ciphers = xstrdup(arg);
813 if (!arg || *arg == '\0')
814 fatal("%s line %d: Missing argument.", filename, linenum);
816 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
817 filename, linenum, arg ? arg : "<NONE>");
818 if (options->macs == NULL)
819 options->macs = xstrdup(arg);
823 intptr = &options->protocol;
825 if (!arg || *arg == '\0')
826 fatal("%s line %d: Missing argument.", filename, linenum);
827 value = proto_spec(arg);
828 if (value == SSH_PROTO_UNKNOWN)
829 fatal("%s line %d: Bad protocol spec '%s'.",
830 filename, linenum, arg ? arg : "<NONE>");
831 if (*intptr == SSH_PROTO_UNKNOWN)
836 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
837 fatal("%s line %d: too many subsystems defined.",
841 if (!arg || *arg == '\0')
842 fatal("%s line %d: Missing subsystem name.",
844 for (i = 0; i < options->num_subsystems; i++)
845 if (strcmp(arg, options->subsystem_name[i]) == 0)
846 fatal("%s line %d: Subsystem '%s' already defined.",
847 filename, linenum, arg);
848 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
850 if (!arg || *arg == '\0')
851 fatal("%s line %d: Missing subsystem command.",
853 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
854 options->num_subsystems++;
859 if (!arg || *arg == '\0')
860 fatal("%s line %d: Missing MaxStartups spec.",
862 if ((n = sscanf(arg, "%d:%d:%d",
863 &options->max_startups_begin,
864 &options->max_startups_rate,
865 &options->max_startups)) == 3) {
866 if (options->max_startups_begin >
867 options->max_startups ||
868 options->max_startups_rate > 100 ||
869 options->max_startups_rate < 1)
870 fatal("%s line %d: Illegal MaxStartups spec.",
873 fatal("%s line %d: Illegal MaxStartups spec.",
876 options->max_startups = options->max_startups_begin;
880 charptr = &options->banner;
883 * These options can contain %X options expanded at
884 * connect time, so that you can specify paths like:
886 * AuthorizedKeysFile /etc/ssh_keys/%u
888 case sAuthorizedKeysFile:
889 case sAuthorizedKeysFile2:
890 charptr = (opcode == sAuthorizedKeysFile ) ?
891 &options->authorized_keys_file :
892 &options->authorized_keys_file2;
895 case sClientAliveInterval:
896 intptr = &options->client_alive_interval;
899 case sClientAliveCountMax:
900 intptr = &options->client_alive_count_max;
904 logit("%s line %d: Deprecated option %s",
905 filename, linenum, arg);
911 logit("%s line %d: Unsupported option %s",
912 filename, linenum, arg);
918 fatal("%s line %d: Missing handler for opcode %s (%d)",
919 filename, linenum, arg, opcode);
921 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
922 fatal("%s line %d: garbage at end of line; \"%.200s\".",
923 filename, linenum, arg);
927 /* Reads the server configuration file. */
930 read_server_config(ServerOptions *options, const char *filename)
932 int linenum, bad_options = 0;
936 debug2("read_server_config: filename %s", filename);
937 f = fopen(filename, "r");
943 while (fgets(line, sizeof(line), f)) {
944 /* Update line number counter. */
946 if (process_server_config_line(options, line, filename, linenum) != 0)
951 fatal("%s: terminating, %d bad configuration options",
952 filename, bad_options);