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.125 2003/08/22 10:56:09 markus Exp $");
20 #include "pathnames.h"
21 #include "tildexpand.h"
27 static void add_listen_addr(ServerOptions *, char *, u_short);
28 static void add_one_listen_addr(ServerOptions *, char *, u_short);
30 /* AF_UNSPEC or AF_INET or AF_INET6 */
32 /* Use of privilege separation or not */
33 extern int use_privsep;
35 /* Initializes the server options to their default values. */
38 initialize_server_options(ServerOptions *options)
40 memset(options, 0, sizeof(*options));
42 /* Portable-specific options */
43 options->use_pam = -1;
45 /* Standard 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->x11_forwarding = -1;
60 options->x11_display_offset = -1;
61 options->x11_use_localhost = -1;
62 options->xauth_location = NULL;
63 options->strict_modes = -1;
64 options->keepalives = -1;
65 options->log_facility = SYSLOG_FACILITY_NOT_SET;
66 options->log_level = SYSLOG_LEVEL_NOT_SET;
67 options->rhosts_rsa_authentication = -1;
68 options->hostbased_authentication = -1;
69 options->hostbased_uses_name_from_packet_only = -1;
70 options->rsa_authentication = -1;
71 options->pubkey_authentication = -1;
72 options->kerberos_authentication = -1;
73 options->kerberos_or_local_passwd = -1;
74 options->kerberos_ticket_cleanup = -1;
75 options->kerberos_tgt_passing = -1;
76 options->gss_authentication=-1;
77 options->gss_cleanup_creds = -1;
78 options->password_authentication = -1;
79 options->kbd_interactive_authentication = -1;
80 options->challenge_response_authentication = -1;
81 options->permit_empty_passwd = -1;
82 options->permit_user_env = -1;
83 options->use_login = -1;
84 options->compression = -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->use_dns = -1;
100 options->client_alive_interval = -1;
101 options->client_alive_count_max = -1;
102 options->authorized_keys_file = NULL;
103 options->authorized_keys_file2 = NULL;
105 /* Needs to be accessable in many places */
110 fill_default_server_options(ServerOptions *options)
112 /* Portable-specific options */
113 if (options->use_pam == -1)
114 options->use_pam = 1;
116 /* Standard Options */
117 if (options->protocol == SSH_PROTO_UNKNOWN)
118 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
119 if (options->num_host_key_files == 0) {
120 /* fill default hostkeys for protocols */
121 if (options->protocol & SSH_PROTO_1)
122 options->host_key_files[options->num_host_key_files++] =
124 if (options->protocol & SSH_PROTO_2) {
125 options->host_key_files[options->num_host_key_files++] =
126 _PATH_HOST_RSA_KEY_FILE;
127 options->host_key_files[options->num_host_key_files++] =
128 _PATH_HOST_DSA_KEY_FILE;
131 if (options->num_ports == 0)
132 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
133 if (options->listen_addrs == NULL)
134 add_listen_addr(options, NULL, 0);
135 if (options->pid_file == NULL)
136 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
137 if (options->server_key_bits == -1)
138 options->server_key_bits = 768;
139 if (options->login_grace_time == -1)
140 options->login_grace_time = 120;
141 if (options->key_regeneration_time == -1)
142 options->key_regeneration_time = 3600;
143 if (options->permit_root_login == PERMIT_NOT_SET)
144 options->permit_root_login = PERMIT_YES;
145 if (options->ignore_rhosts == -1)
146 options->ignore_rhosts = 1;
147 if (options->ignore_user_known_hosts == -1)
148 options->ignore_user_known_hosts = 0;
149 if (options->print_motd == -1)
150 options->print_motd = 1;
151 if (options->print_lastlog == -1)
152 options->print_lastlog = 1;
153 if (options->x11_forwarding == -1)
154 options->x11_forwarding = 0;
155 if (options->x11_display_offset == -1)
156 options->x11_display_offset = 10;
157 if (options->x11_use_localhost == -1)
158 options->x11_use_localhost = 1;
159 if (options->xauth_location == NULL)
160 options->xauth_location = _PATH_XAUTH;
161 if (options->strict_modes == -1)
162 options->strict_modes = 1;
163 if (options->keepalives == -1)
164 options->keepalives = 1;
165 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
166 options->log_facility = SYSLOG_FACILITY_AUTH;
167 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
168 options->log_level = SYSLOG_LEVEL_INFO;
169 if (options->rhosts_rsa_authentication == -1)
170 options->rhosts_rsa_authentication = 0;
171 if (options->hostbased_authentication == -1)
172 options->hostbased_authentication = 0;
173 if (options->hostbased_uses_name_from_packet_only == -1)
174 options->hostbased_uses_name_from_packet_only = 0;
175 if (options->rsa_authentication == -1)
176 options->rsa_authentication = 1;
177 if (options->pubkey_authentication == -1)
178 options->pubkey_authentication = 1;
179 if (options->kerberos_authentication == -1)
180 options->kerberos_authentication = 0;
181 if (options->kerberos_or_local_passwd == -1)
182 options->kerberos_or_local_passwd = 1;
183 if (options->kerberos_ticket_cleanup == -1)
184 options->kerberos_ticket_cleanup = 1;
185 if (options->kerberos_tgt_passing == -1)
186 options->kerberos_tgt_passing = 0;
187 if (options->gss_authentication == -1)
188 options->gss_authentication = 0;
189 if (options->gss_cleanup_creds == -1)
190 options->gss_cleanup_creds = 1;
191 if (options->password_authentication == -1)
192 options->password_authentication = 1;
193 if (options->kbd_interactive_authentication == -1)
194 options->kbd_interactive_authentication = 0;
195 if (options->challenge_response_authentication == -1)
196 options->challenge_response_authentication = 1;
197 if (options->permit_empty_passwd == -1)
198 options->permit_empty_passwd = 0;
199 if (options->permit_user_env == -1)
200 options->permit_user_env = 0;
201 if (options->use_login == -1)
202 options->use_login = 0;
203 if (options->compression == -1)
204 options->compression = 1;
205 if (options->allow_tcp_forwarding == -1)
206 options->allow_tcp_forwarding = 1;
207 if (options->gateway_ports == -1)
208 options->gateway_ports = 0;
209 if (options->max_startups == -1)
210 options->max_startups = 10;
211 if (options->max_startups_rate == -1)
212 options->max_startups_rate = 100; /* 100% */
213 if (options->max_startups_begin == -1)
214 options->max_startups_begin = options->max_startups;
215 if (options->use_dns == -1)
216 options->use_dns = 1;
217 if (options->client_alive_interval == -1)
218 options->client_alive_interval = 0;
219 if (options->client_alive_count_max == -1)
220 options->client_alive_count_max = 3;
221 if (options->authorized_keys_file2 == NULL) {
222 /* authorized_keys_file2 falls back to authorized_keys_file */
223 if (options->authorized_keys_file != NULL)
224 options->authorized_keys_file2 = options->authorized_keys_file;
226 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
228 if (options->authorized_keys_file == NULL)
229 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
231 /* Turn privilege separation on by default */
232 if (use_privsep == -1)
236 if (use_privsep && options->compression == 1) {
237 error("This platform does not support both privilege "
238 "separation and compression");
239 error("Compression disabled");
240 options->compression = 0;
246 /* Keyword tokens. */
248 sBadOption, /* == unknown option */
249 /* Portable-specific options */
251 /* Standard Options */
252 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
253 sPermitRootLogin, sLogFacility, sLogLevel,
254 sRhostsRSAAuthentication, sRSAAuthentication,
255 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
256 sKerberosTgtPassing, sChallengeResponseAuthentication,
257 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
258 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
259 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
260 sStrictModes, sEmptyPasswd, sKeepAlives,
261 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
262 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
263 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
264 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
265 sBanner, sUseDNS, sHostbasedAuthentication,
266 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
267 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
268 sGssAuthentication, sGssCleanupCreds,
269 sUsePrivilegeSeparation,
270 sDeprecated, sUnsupported
273 /* Textual representation of the tokens. */
276 ServerOpCodes opcode;
278 /* Portable-specific options */
280 { "usepam", sUsePAM },
282 { "usepam", sUnsupported },
284 { "pamauthenticationviakbdint", sDeprecated },
285 /* Standard Options */
287 { "hostkey", sHostKeyFile },
288 { "hostdsakey", sHostKeyFile }, /* alias */
289 { "pidfile", sPidFile },
290 { "serverkeybits", sServerKeyBits },
291 { "logingracetime", sLoginGraceTime },
292 { "keyregenerationinterval", sKeyRegenerationTime },
293 { "permitrootlogin", sPermitRootLogin },
294 { "syslogfacility", sLogFacility },
295 { "loglevel", sLogLevel },
296 { "rhostsauthentication", sDeprecated },
297 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
298 { "hostbasedauthentication", sHostbasedAuthentication },
299 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
300 { "rsaauthentication", sRSAAuthentication },
301 { "pubkeyauthentication", sPubkeyAuthentication },
302 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
304 { "kerberosauthentication", sKerberosAuthentication },
305 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
306 { "kerberosticketcleanup", sKerberosTicketCleanup },
307 { "kerberostgtpassing", sKerberosTgtPassing },
309 { "kerberosauthentication", sUnsupported },
310 { "kerberosorlocalpasswd", sUnsupported },
311 { "kerberosticketcleanup", sUnsupported },
312 { "kerberostgtpassing", sUnsupported },
314 { "afstokenpassing", sUnsupported },
316 { "gssapiauthentication", sGssAuthentication },
317 { "gssapicleanupcreds", sGssCleanupCreds },
319 { "gssapiauthentication", sUnsupported },
320 { "gssapicleanupcreds", sUnsupported },
322 { "passwordauthentication", sPasswordAuthentication },
323 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
324 { "challengeresponseauthentication", sChallengeResponseAuthentication },
325 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
326 { "checkmail", sDeprecated },
327 { "listenaddress", sListenAddress },
328 { "printmotd", sPrintMotd },
329 { "printlastlog", sPrintLastLog },
330 { "ignorerhosts", sIgnoreRhosts },
331 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
332 { "x11forwarding", sX11Forwarding },
333 { "x11displayoffset", sX11DisplayOffset },
334 { "x11uselocalhost", sX11UseLocalhost },
335 { "xauthlocation", sXAuthLocation },
336 { "strictmodes", sStrictModes },
337 { "permitemptypasswords", sEmptyPasswd },
338 { "permituserenvironment", sPermitUserEnvironment },
339 { "uselogin", sUseLogin },
340 { "compression", sCompression },
341 { "keepalive", sKeepAlives },
342 { "allowtcpforwarding", sAllowTcpForwarding },
343 { "allowusers", sAllowUsers },
344 { "denyusers", sDenyUsers },
345 { "allowgroups", sAllowGroups },
346 { "denygroups", sDenyGroups },
347 { "ciphers", sCiphers },
349 { "protocol", sProtocol },
350 { "gatewayports", sGatewayPorts },
351 { "subsystem", sSubsystem },
352 { "maxstartups", sMaxStartups },
353 { "banner", sBanner },
354 { "usedns", sUseDNS },
355 { "verifyreversemapping", sDeprecated },
356 { "reversemappingcheck", sDeprecated },
357 { "clientaliveinterval", sClientAliveInterval },
358 { "clientalivecountmax", sClientAliveCountMax },
359 { "authorizedkeysfile", sAuthorizedKeysFile },
360 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
361 { "useprivilegeseparation", sUsePrivilegeSeparation},
366 * Returns the number of the token pointed to by cp or sBadOption.
370 parse_token(const char *cp, const char *filename,
375 for (i = 0; keywords[i].name; i++)
376 if (strcasecmp(cp, keywords[i].name) == 0)
377 return keywords[i].opcode;
379 error("%s: line %d: Bad configuration option: %s",
380 filename, linenum, cp);
385 add_listen_addr(ServerOptions *options, char *addr, u_short port)
389 if (options->num_ports == 0)
390 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
392 for (i = 0; i < options->num_ports; i++)
393 add_one_listen_addr(options, addr, options->ports[i]);
395 add_one_listen_addr(options, addr, port);
399 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
401 struct addrinfo hints, *ai, *aitop;
402 char strport[NI_MAXSERV];
405 memset(&hints, 0, sizeof(hints));
406 hints.ai_family = IPv4or6;
407 hints.ai_socktype = SOCK_STREAM;
408 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
409 snprintf(strport, sizeof strport, "%u", port);
410 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
411 fatal("bad addr or host: %s (%s)",
412 addr ? addr : "<NULL>",
413 gai_strerror(gaierr));
414 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
416 ai->ai_next = options->listen_addrs;
417 options->listen_addrs = aitop;
421 process_server_config_line(ServerOptions *options, char *line,
422 const char *filename, int linenum)
424 char *cp, **charptr, *arg, *p;
425 int *intptr, value, i, n;
426 ServerOpCodes opcode;
430 /* Ignore leading whitespace */
433 if (!arg || !*arg || *arg == '#')
437 opcode = parse_token(arg, filename, linenum);
439 /* Portable-specific options */
441 intptr = &options->use_pam;
444 /* Standard Options */
448 /* ignore ports from configfile if cmdline specifies ports */
449 if (options->ports_from_cmdline)
451 if (options->listen_addrs != NULL)
452 fatal("%s line %d: ports must be specified before "
453 "ListenAddress.", filename, linenum);
454 if (options->num_ports >= MAX_PORTS)
455 fatal("%s line %d: too many ports.",
458 if (!arg || *arg == '\0')
459 fatal("%s line %d: missing port number.",
461 options->ports[options->num_ports++] = a2port(arg);
462 if (options->ports[options->num_ports-1] == 0)
463 fatal("%s line %d: Badly formatted port number.",
468 intptr = &options->server_key_bits;
471 if (!arg || *arg == '\0')
472 fatal("%s line %d: missing integer value.",
479 case sLoginGraceTime:
480 intptr = &options->login_grace_time;
483 if (!arg || *arg == '\0')
484 fatal("%s line %d: missing time value.",
486 if ((value = convtime(arg)) == -1)
487 fatal("%s line %d: invalid time value.",
493 case sKeyRegenerationTime:
494 intptr = &options->key_regeneration_time;
499 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
500 fatal("%s line %d: missing inet addr.",
503 if ((p = strchr(arg, ']')) == NULL)
504 fatal("%s line %d: bad ipv6 inet addr usage.",
507 memmove(p, p+1, strlen(p+1)+1);
508 } else if (((p = strchr(arg, ':')) == NULL) ||
509 (strchr(p+1, ':') != NULL)) {
510 add_listen_addr(options, arg, 0);
518 fatal("%s line %d: bad inet addr:port usage.",
522 if ((port = a2port(p)) == 0)
523 fatal("%s line %d: bad port number.",
525 add_listen_addr(options, arg, port);
527 } else if (*p == '\0')
528 add_listen_addr(options, arg, 0);
530 fatal("%s line %d: bad inet addr usage.",
535 intptr = &options->num_host_key_files;
536 if (*intptr >= MAX_HOSTKEYS)
537 fatal("%s line %d: too many host keys specified (max %d).",
538 filename, linenum, MAX_HOSTKEYS);
539 charptr = &options->host_key_files[*intptr];
542 if (!arg || *arg == '\0')
543 fatal("%s line %d: missing file name.",
545 if (*charptr == NULL) {
546 *charptr = tilde_expand_filename(arg, getuid());
547 /* increase optional counter */
549 *intptr = *intptr + 1;
554 charptr = &options->pid_file;
557 case sPermitRootLogin:
558 intptr = &options->permit_root_login;
560 if (!arg || *arg == '\0')
561 fatal("%s line %d: missing yes/"
562 "without-password/forced-commands-only/no "
563 "argument.", filename, linenum);
564 value = 0; /* silence compiler */
565 if (strcmp(arg, "without-password") == 0)
566 value = PERMIT_NO_PASSWD;
567 else if (strcmp(arg, "forced-commands-only") == 0)
568 value = PERMIT_FORCED_ONLY;
569 else if (strcmp(arg, "yes") == 0)
571 else if (strcmp(arg, "no") == 0)
574 fatal("%s line %d: Bad yes/"
575 "without-password/forced-commands-only/no "
576 "argument: %s", filename, linenum, arg);
582 intptr = &options->ignore_rhosts;
585 if (!arg || *arg == '\0')
586 fatal("%s line %d: missing yes/no argument.",
588 value = 0; /* silence compiler */
589 if (strcmp(arg, "yes") == 0)
591 else if (strcmp(arg, "no") == 0)
594 fatal("%s line %d: Bad yes/no argument: %s",
595 filename, linenum, arg);
600 case sIgnoreUserKnownHosts:
601 intptr = &options->ignore_user_known_hosts;
604 case sRhostsRSAAuthentication:
605 intptr = &options->rhosts_rsa_authentication;
608 case sHostbasedAuthentication:
609 intptr = &options->hostbased_authentication;
612 case sHostbasedUsesNameFromPacketOnly:
613 intptr = &options->hostbased_uses_name_from_packet_only;
616 case sRSAAuthentication:
617 intptr = &options->rsa_authentication;
620 case sPubkeyAuthentication:
621 intptr = &options->pubkey_authentication;
624 case sKerberosAuthentication:
625 intptr = &options->kerberos_authentication;
628 case sKerberosOrLocalPasswd:
629 intptr = &options->kerberos_or_local_passwd;
632 case sKerberosTicketCleanup:
633 intptr = &options->kerberos_ticket_cleanup;
636 case sKerberosTgtPassing:
637 intptr = &options->kerberos_tgt_passing;
640 case sGssAuthentication:
641 intptr = &options->gss_authentication;
644 case sGssCleanupCreds:
645 intptr = &options->gss_cleanup_creds;
648 case sPasswordAuthentication:
649 intptr = &options->password_authentication;
652 case sKbdInteractiveAuthentication:
653 intptr = &options->kbd_interactive_authentication;
656 case sChallengeResponseAuthentication:
657 intptr = &options->challenge_response_authentication;
661 intptr = &options->print_motd;
665 intptr = &options->print_lastlog;
669 intptr = &options->x11_forwarding;
672 case sX11DisplayOffset:
673 intptr = &options->x11_display_offset;
676 case sX11UseLocalhost:
677 intptr = &options->x11_use_localhost;
681 charptr = &options->xauth_location;
685 intptr = &options->strict_modes;
689 intptr = &options->keepalives;
693 intptr = &options->permit_empty_passwd;
696 case sPermitUserEnvironment:
697 intptr = &options->permit_user_env;
701 intptr = &options->use_login;
705 intptr = &options->compression;
709 intptr = &options->gateway_ports;
713 intptr = &options->use_dns;
717 intptr = (int *) &options->log_facility;
719 value = log_facility_number(arg);
720 if (value == SYSLOG_FACILITY_NOT_SET)
721 fatal("%.200s line %d: unsupported log facility '%s'",
722 filename, linenum, arg ? arg : "<NONE>");
724 *intptr = (SyslogFacility) value;
728 intptr = (int *) &options->log_level;
730 value = log_level_number(arg);
731 if (value == SYSLOG_LEVEL_NOT_SET)
732 fatal("%.200s line %d: unsupported log level '%s'",
733 filename, linenum, arg ? arg : "<NONE>");
735 *intptr = (LogLevel) value;
738 case sAllowTcpForwarding:
739 intptr = &options->allow_tcp_forwarding;
742 case sUsePrivilegeSeparation:
743 intptr = &use_privsep;
747 while ((arg = strdelim(&cp)) && *arg != '\0') {
748 if (options->num_allow_users >= MAX_ALLOW_USERS)
749 fatal("%s line %d: too many allow users.",
751 options->allow_users[options->num_allow_users++] =
757 while ((arg = strdelim(&cp)) && *arg != '\0') {
758 if (options->num_deny_users >= MAX_DENY_USERS)
759 fatal( "%s line %d: too many deny users.",
761 options->deny_users[options->num_deny_users++] =
767 while ((arg = strdelim(&cp)) && *arg != '\0') {
768 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
769 fatal("%s line %d: too many allow groups.",
771 options->allow_groups[options->num_allow_groups++] =
777 while ((arg = strdelim(&cp)) && *arg != '\0') {
778 if (options->num_deny_groups >= MAX_DENY_GROUPS)
779 fatal("%s line %d: too many deny groups.",
781 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
787 if (!arg || *arg == '\0')
788 fatal("%s line %d: Missing argument.", filename, linenum);
789 if (!ciphers_valid(arg))
790 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
791 filename, linenum, arg ? arg : "<NONE>");
792 if (options->ciphers == NULL)
793 options->ciphers = xstrdup(arg);
798 if (!arg || *arg == '\0')
799 fatal("%s line %d: Missing argument.", filename, linenum);
801 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
802 filename, linenum, arg ? arg : "<NONE>");
803 if (options->macs == NULL)
804 options->macs = xstrdup(arg);
808 intptr = &options->protocol;
810 if (!arg || *arg == '\0')
811 fatal("%s line %d: Missing argument.", filename, linenum);
812 value = proto_spec(arg);
813 if (value == SSH_PROTO_UNKNOWN)
814 fatal("%s line %d: Bad protocol spec '%s'.",
815 filename, linenum, arg ? arg : "<NONE>");
816 if (*intptr == SSH_PROTO_UNKNOWN)
821 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
822 fatal("%s line %d: too many subsystems defined.",
826 if (!arg || *arg == '\0')
827 fatal("%s line %d: Missing subsystem name.",
829 for (i = 0; i < options->num_subsystems; i++)
830 if (strcmp(arg, options->subsystem_name[i]) == 0)
831 fatal("%s line %d: Subsystem '%s' already defined.",
832 filename, linenum, arg);
833 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
835 if (!arg || *arg == '\0')
836 fatal("%s line %d: Missing subsystem command.",
838 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
839 options->num_subsystems++;
844 if (!arg || *arg == '\0')
845 fatal("%s line %d: Missing MaxStartups spec.",
847 if ((n = sscanf(arg, "%d:%d:%d",
848 &options->max_startups_begin,
849 &options->max_startups_rate,
850 &options->max_startups)) == 3) {
851 if (options->max_startups_begin >
852 options->max_startups ||
853 options->max_startups_rate > 100 ||
854 options->max_startups_rate < 1)
855 fatal("%s line %d: Illegal MaxStartups spec.",
858 fatal("%s line %d: Illegal MaxStartups spec.",
861 options->max_startups = options->max_startups_begin;
865 charptr = &options->banner;
868 * These options can contain %X options expanded at
869 * connect time, so that you can specify paths like:
871 * AuthorizedKeysFile /etc/ssh_keys/%u
873 case sAuthorizedKeysFile:
874 case sAuthorizedKeysFile2:
875 charptr = (opcode == sAuthorizedKeysFile ) ?
876 &options->authorized_keys_file :
877 &options->authorized_keys_file2;
880 case sClientAliveInterval:
881 intptr = &options->client_alive_interval;
884 case sClientAliveCountMax:
885 intptr = &options->client_alive_count_max;
889 logit("%s line %d: Deprecated option %s",
890 filename, linenum, arg);
896 logit("%s line %d: Unsupported option %s",
897 filename, linenum, arg);
903 fatal("%s line %d: Missing handler for opcode %s (%d)",
904 filename, linenum, arg, opcode);
906 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
907 fatal("%s line %d: garbage at end of line; \"%.200s\".",
908 filename, linenum, arg);
912 /* Reads the server configuration file. */
915 read_server_config(ServerOptions *options, const char *filename)
917 int linenum, bad_options = 0;
921 debug2("read_server_config: filename %s", filename);
922 f = fopen(filename, "r");
928 while (fgets(line, sizeof(line), f)) {
929 /* Update line number counter. */
931 if (process_server_config_line(options, line, filename, linenum) != 0)
936 fatal("%s: terminating, %d bad configuration options",
937 filename, bad_options);