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.126 2003/08/28 12:54:34 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 },
308 { "kerberosauthentication", sUnsupported },
309 { "kerberosorlocalpasswd", sUnsupported },
310 { "kerberosticketcleanup", sUnsupported },
312 { "kerberostgtpassing", sUnsupported },
313 { "afstokenpassing", sUnsupported },
315 { "gssapiauthentication", sGssAuthentication },
316 { "gssapicleanupcreds", sGssCleanupCreds },
318 { "gssapiauthentication", sUnsupported },
319 { "gssapicleanupcreds", sUnsupported },
321 { "passwordauthentication", sPasswordAuthentication },
322 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
323 { "challengeresponseauthentication", sChallengeResponseAuthentication },
324 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
325 { "checkmail", sDeprecated },
326 { "listenaddress", sListenAddress },
327 { "printmotd", sPrintMotd },
328 { "printlastlog", sPrintLastLog },
329 { "ignorerhosts", sIgnoreRhosts },
330 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
331 { "x11forwarding", sX11Forwarding },
332 { "x11displayoffset", sX11DisplayOffset },
333 { "x11uselocalhost", sX11UseLocalhost },
334 { "xauthlocation", sXAuthLocation },
335 { "strictmodes", sStrictModes },
336 { "permitemptypasswords", sEmptyPasswd },
337 { "permituserenvironment", sPermitUserEnvironment },
338 { "uselogin", sUseLogin },
339 { "compression", sCompression },
340 { "keepalive", sKeepAlives },
341 { "allowtcpforwarding", sAllowTcpForwarding },
342 { "allowusers", sAllowUsers },
343 { "denyusers", sDenyUsers },
344 { "allowgroups", sAllowGroups },
345 { "denygroups", sDenyGroups },
346 { "ciphers", sCiphers },
348 { "protocol", sProtocol },
349 { "gatewayports", sGatewayPorts },
350 { "subsystem", sSubsystem },
351 { "maxstartups", sMaxStartups },
352 { "banner", sBanner },
353 { "usedns", sUseDNS },
354 { "verifyreversemapping", sDeprecated },
355 { "reversemappingcheck", sDeprecated },
356 { "clientaliveinterval", sClientAliveInterval },
357 { "clientalivecountmax", sClientAliveCountMax },
358 { "authorizedkeysfile", sAuthorizedKeysFile },
359 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
360 { "useprivilegeseparation", sUsePrivilegeSeparation},
365 * Returns the number of the token pointed to by cp or sBadOption.
369 parse_token(const char *cp, const char *filename,
374 for (i = 0; keywords[i].name; i++)
375 if (strcasecmp(cp, keywords[i].name) == 0)
376 return keywords[i].opcode;
378 error("%s: line %d: Bad configuration option: %s",
379 filename, linenum, cp);
384 add_listen_addr(ServerOptions *options, char *addr, u_short port)
388 if (options->num_ports == 0)
389 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
391 for (i = 0; i < options->num_ports; i++)
392 add_one_listen_addr(options, addr, options->ports[i]);
394 add_one_listen_addr(options, addr, port);
398 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
400 struct addrinfo hints, *ai, *aitop;
401 char strport[NI_MAXSERV];
404 memset(&hints, 0, sizeof(hints));
405 hints.ai_family = IPv4or6;
406 hints.ai_socktype = SOCK_STREAM;
407 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
408 snprintf(strport, sizeof strport, "%u", port);
409 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
410 fatal("bad addr or host: %s (%s)",
411 addr ? addr : "<NULL>",
412 gai_strerror(gaierr));
413 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
415 ai->ai_next = options->listen_addrs;
416 options->listen_addrs = aitop;
420 process_server_config_line(ServerOptions *options, char *line,
421 const char *filename, int linenum)
423 char *cp, **charptr, *arg, *p;
424 int *intptr, value, i, n;
425 ServerOpCodes opcode;
429 /* Ignore leading whitespace */
432 if (!arg || !*arg || *arg == '#')
436 opcode = parse_token(arg, filename, linenum);
438 /* Portable-specific options */
440 intptr = &options->use_pam;
443 /* Standard Options */
447 /* ignore ports from configfile if cmdline specifies ports */
448 if (options->ports_from_cmdline)
450 if (options->listen_addrs != NULL)
451 fatal("%s line %d: ports must be specified before "
452 "ListenAddress.", filename, linenum);
453 if (options->num_ports >= MAX_PORTS)
454 fatal("%s line %d: too many ports.",
457 if (!arg || *arg == '\0')
458 fatal("%s line %d: missing port number.",
460 options->ports[options->num_ports++] = a2port(arg);
461 if (options->ports[options->num_ports-1] == 0)
462 fatal("%s line %d: Badly formatted port number.",
467 intptr = &options->server_key_bits;
470 if (!arg || *arg == '\0')
471 fatal("%s line %d: missing integer value.",
478 case sLoginGraceTime:
479 intptr = &options->login_grace_time;
482 if (!arg || *arg == '\0')
483 fatal("%s line %d: missing time value.",
485 if ((value = convtime(arg)) == -1)
486 fatal("%s line %d: invalid time value.",
492 case sKeyRegenerationTime:
493 intptr = &options->key_regeneration_time;
498 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
499 fatal("%s line %d: missing inet addr.",
502 if ((p = strchr(arg, ']')) == NULL)
503 fatal("%s line %d: bad ipv6 inet addr usage.",
506 memmove(p, p+1, strlen(p+1)+1);
507 } else if (((p = strchr(arg, ':')) == NULL) ||
508 (strchr(p+1, ':') != NULL)) {
509 add_listen_addr(options, arg, 0);
517 fatal("%s line %d: bad inet addr:port usage.",
521 if ((port = a2port(p)) == 0)
522 fatal("%s line %d: bad port number.",
524 add_listen_addr(options, arg, port);
526 } else if (*p == '\0')
527 add_listen_addr(options, arg, 0);
529 fatal("%s line %d: bad inet addr usage.",
534 intptr = &options->num_host_key_files;
535 if (*intptr >= MAX_HOSTKEYS)
536 fatal("%s line %d: too many host keys specified (max %d).",
537 filename, linenum, MAX_HOSTKEYS);
538 charptr = &options->host_key_files[*intptr];
541 if (!arg || *arg == '\0')
542 fatal("%s line %d: missing file name.",
544 if (*charptr == NULL) {
545 *charptr = tilde_expand_filename(arg, getuid());
546 /* increase optional counter */
548 *intptr = *intptr + 1;
553 charptr = &options->pid_file;
556 case sPermitRootLogin:
557 intptr = &options->permit_root_login;
559 if (!arg || *arg == '\0')
560 fatal("%s line %d: missing yes/"
561 "without-password/forced-commands-only/no "
562 "argument.", filename, linenum);
563 value = 0; /* silence compiler */
564 if (strcmp(arg, "without-password") == 0)
565 value = PERMIT_NO_PASSWD;
566 else if (strcmp(arg, "forced-commands-only") == 0)
567 value = PERMIT_FORCED_ONLY;
568 else if (strcmp(arg, "yes") == 0)
570 else if (strcmp(arg, "no") == 0)
573 fatal("%s line %d: Bad yes/"
574 "without-password/forced-commands-only/no "
575 "argument: %s", filename, linenum, arg);
581 intptr = &options->ignore_rhosts;
584 if (!arg || *arg == '\0')
585 fatal("%s line %d: missing yes/no argument.",
587 value = 0; /* silence compiler */
588 if (strcmp(arg, "yes") == 0)
590 else if (strcmp(arg, "no") == 0)
593 fatal("%s line %d: Bad yes/no argument: %s",
594 filename, linenum, arg);
599 case sIgnoreUserKnownHosts:
600 intptr = &options->ignore_user_known_hosts;
603 case sRhostsRSAAuthentication:
604 intptr = &options->rhosts_rsa_authentication;
607 case sHostbasedAuthentication:
608 intptr = &options->hostbased_authentication;
611 case sHostbasedUsesNameFromPacketOnly:
612 intptr = &options->hostbased_uses_name_from_packet_only;
615 case sRSAAuthentication:
616 intptr = &options->rsa_authentication;
619 case sPubkeyAuthentication:
620 intptr = &options->pubkey_authentication;
623 case sKerberosAuthentication:
624 intptr = &options->kerberos_authentication;
627 case sKerberosOrLocalPasswd:
628 intptr = &options->kerberos_or_local_passwd;
631 case sKerberosTicketCleanup:
632 intptr = &options->kerberos_ticket_cleanup;
635 case sKerberosTgtPassing:
636 intptr = &options->kerberos_tgt_passing;
639 case sGssAuthentication:
640 intptr = &options->gss_authentication;
643 case sGssCleanupCreds:
644 intptr = &options->gss_cleanup_creds;
647 case sPasswordAuthentication:
648 intptr = &options->password_authentication;
651 case sKbdInteractiveAuthentication:
652 intptr = &options->kbd_interactive_authentication;
655 case sChallengeResponseAuthentication:
656 intptr = &options->challenge_response_authentication;
660 intptr = &options->print_motd;
664 intptr = &options->print_lastlog;
668 intptr = &options->x11_forwarding;
671 case sX11DisplayOffset:
672 intptr = &options->x11_display_offset;
675 case sX11UseLocalhost:
676 intptr = &options->x11_use_localhost;
680 charptr = &options->xauth_location;
684 intptr = &options->strict_modes;
688 intptr = &options->keepalives;
692 intptr = &options->permit_empty_passwd;
695 case sPermitUserEnvironment:
696 intptr = &options->permit_user_env;
700 intptr = &options->use_login;
704 intptr = &options->compression;
708 intptr = &options->gateway_ports;
712 intptr = &options->use_dns;
716 intptr = (int *) &options->log_facility;
718 value = log_facility_number(arg);
719 if (value == SYSLOG_FACILITY_NOT_SET)
720 fatal("%.200s line %d: unsupported log facility '%s'",
721 filename, linenum, arg ? arg : "<NONE>");
723 *intptr = (SyslogFacility) value;
727 intptr = (int *) &options->log_level;
729 value = log_level_number(arg);
730 if (value == SYSLOG_LEVEL_NOT_SET)
731 fatal("%.200s line %d: unsupported log level '%s'",
732 filename, linenum, arg ? arg : "<NONE>");
734 *intptr = (LogLevel) value;
737 case sAllowTcpForwarding:
738 intptr = &options->allow_tcp_forwarding;
741 case sUsePrivilegeSeparation:
742 intptr = &use_privsep;
746 while ((arg = strdelim(&cp)) && *arg != '\0') {
747 if (options->num_allow_users >= MAX_ALLOW_USERS)
748 fatal("%s line %d: too many allow users.",
750 options->allow_users[options->num_allow_users++] =
756 while ((arg = strdelim(&cp)) && *arg != '\0') {
757 if (options->num_deny_users >= MAX_DENY_USERS)
758 fatal( "%s line %d: too many deny users.",
760 options->deny_users[options->num_deny_users++] =
766 while ((arg = strdelim(&cp)) && *arg != '\0') {
767 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
768 fatal("%s line %d: too many allow groups.",
770 options->allow_groups[options->num_allow_groups++] =
776 while ((arg = strdelim(&cp)) && *arg != '\0') {
777 if (options->num_deny_groups >= MAX_DENY_GROUPS)
778 fatal("%s line %d: too many deny groups.",
780 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
786 if (!arg || *arg == '\0')
787 fatal("%s line %d: Missing argument.", filename, linenum);
788 if (!ciphers_valid(arg))
789 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
790 filename, linenum, arg ? arg : "<NONE>");
791 if (options->ciphers == NULL)
792 options->ciphers = xstrdup(arg);
797 if (!arg || *arg == '\0')
798 fatal("%s line %d: Missing argument.", filename, linenum);
800 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
801 filename, linenum, arg ? arg : "<NONE>");
802 if (options->macs == NULL)
803 options->macs = xstrdup(arg);
807 intptr = &options->protocol;
809 if (!arg || *arg == '\0')
810 fatal("%s line %d: Missing argument.", filename, linenum);
811 value = proto_spec(arg);
812 if (value == SSH_PROTO_UNKNOWN)
813 fatal("%s line %d: Bad protocol spec '%s'.",
814 filename, linenum, arg ? arg : "<NONE>");
815 if (*intptr == SSH_PROTO_UNKNOWN)
820 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
821 fatal("%s line %d: too many subsystems defined.",
825 if (!arg || *arg == '\0')
826 fatal("%s line %d: Missing subsystem name.",
828 for (i = 0; i < options->num_subsystems; i++)
829 if (strcmp(arg, options->subsystem_name[i]) == 0)
830 fatal("%s line %d: Subsystem '%s' already defined.",
831 filename, linenum, arg);
832 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
834 if (!arg || *arg == '\0')
835 fatal("%s line %d: Missing subsystem command.",
837 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
838 options->num_subsystems++;
843 if (!arg || *arg == '\0')
844 fatal("%s line %d: Missing MaxStartups spec.",
846 if ((n = sscanf(arg, "%d:%d:%d",
847 &options->max_startups_begin,
848 &options->max_startups_rate,
849 &options->max_startups)) == 3) {
850 if (options->max_startups_begin >
851 options->max_startups ||
852 options->max_startups_rate > 100 ||
853 options->max_startups_rate < 1)
854 fatal("%s line %d: Illegal MaxStartups spec.",
857 fatal("%s line %d: Illegal MaxStartups spec.",
860 options->max_startups = options->max_startups_begin;
864 charptr = &options->banner;
867 * These options can contain %X options expanded at
868 * connect time, so that you can specify paths like:
870 * AuthorizedKeysFile /etc/ssh_keys/%u
872 case sAuthorizedKeysFile:
873 case sAuthorizedKeysFile2:
874 charptr = (opcode == sAuthorizedKeysFile ) ?
875 &options->authorized_keys_file :
876 &options->authorized_keys_file2;
879 case sClientAliveInterval:
880 intptr = &options->client_alive_interval;
883 case sClientAliveCountMax:
884 intptr = &options->client_alive_count_max;
888 logit("%s line %d: Deprecated option %s",
889 filename, linenum, arg);
895 logit("%s line %d: Unsupported option %s",
896 filename, linenum, arg);
902 fatal("%s line %d: Missing handler for opcode %s (%d)",
903 filename, linenum, arg, opcode);
905 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
906 fatal("%s line %d: garbage at end of line; \"%.200s\".",
907 filename, linenum, arg);
911 /* Reads the server configuration file. */
914 read_server_config(ServerOptions *options, const char *filename)
916 int linenum, bad_options = 0;
920 debug2("read_server_config: filename %s", filename);
921 f = fopen(filename, "r");
927 while (fgets(line, sizeof(line), f)) {
928 /* Update line number counter. */
930 if (process_server_config_line(options, line, filename, linenum) != 0)
935 fatal("%s: terminating, %d bad configuration options",
936 filename, bad_options);