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.109 2002/05/15 21:02:52 markus Exp $");
22 /* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
24 #define KEYFILE "/etc/krb5.keytab"
36 #include "pathnames.h"
37 #include "tildexpand.h"
43 static void add_listen_addr(ServerOptions *, char *, u_short);
44 static void add_one_listen_addr(ServerOptions *, char *, u_short);
46 /* AF_UNSPEC or AF_INET or AF_INET6 */
48 /* Use of privilege separation or not */
49 extern int use_privsep;
51 /* Initializes the server options to their default values. */
54 initialize_server_options(ServerOptions *options)
56 memset(options, 0, sizeof(*options));
58 /* Portable-specific options */
59 options->pam_authentication_via_kbd_int = -1;
61 /* Standard Options */
62 options->num_ports = 0;
63 options->ports_from_cmdline = 0;
64 options->listen_addrs = NULL;
65 options->num_host_key_files = 0;
66 options->pid_file = NULL;
67 options->server_key_bits = -1;
68 options->login_grace_time = -1;
69 options->key_regeneration_time = -1;
70 options->permit_root_login = PERMIT_NOT_SET;
71 options->ignore_rhosts = -1;
72 options->ignore_user_known_hosts = -1;
73 options->print_motd = -1;
74 options->print_lastlog = -1;
75 options->x11_forwarding = -1;
76 options->x11_display_offset = -1;
77 options->x11_use_localhost = -1;
78 options->xauth_location = NULL;
79 options->strict_modes = -1;
80 options->keepalives = -1;
81 options->log_facility = SYSLOG_FACILITY_NOT_SET;
82 options->log_level = SYSLOG_LEVEL_NOT_SET;
83 options->rhosts_authentication = -1;
84 options->rhosts_rsa_authentication = -1;
85 options->hostbased_authentication = -1;
86 options->hostbased_uses_name_from_packet_only = -1;
87 options->rsa_authentication = -1;
88 options->pubkey_authentication = -1;
90 options->gss_authentication=-1;
91 options->gss_keyex=-1;
92 options->gss_use_session_ccache = -1;
93 options->gss_cleanup_creds = -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->use_login = -1;
111 options->allow_tcp_forwarding = -1;
112 options->num_allow_users = 0;
113 options->num_deny_users = 0;
114 options->num_allow_groups = 0;
115 options->num_deny_groups = 0;
116 options->ciphers = NULL;
117 options->macs = NULL;
118 options->protocol = SSH_PROTO_UNKNOWN;
119 options->gateway_ports = -1;
120 options->num_subsystems = 0;
121 options->max_startups_begin = -1;
122 options->max_startups_rate = -1;
123 options->max_startups = -1;
124 options->banner = NULL;
125 options->verify_reverse_mapping = -1;
126 options->client_alive_interval = -1;
127 options->client_alive_count_max = -1;
128 options->authorized_keys_file = NULL;
129 options->authorized_keys_file2 = NULL;
131 /* Needs to be accessable in many places */
136 fill_default_server_options(ServerOptions *options)
138 /* Portable-specific options */
139 if (options->pam_authentication_via_kbd_int == -1)
140 options->pam_authentication_via_kbd_int = 0;
142 /* Standard Options */
143 if (options->protocol == SSH_PROTO_UNKNOWN)
144 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
145 if (options->num_host_key_files == 0) {
146 /* fill default hostkeys for protocols */
147 if (options->protocol & SSH_PROTO_1)
148 options->host_key_files[options->num_host_key_files++] =
150 if (options->protocol & SSH_PROTO_2) {
151 options->host_key_files[options->num_host_key_files++] =
152 _PATH_HOST_RSA_KEY_FILE;
153 options->host_key_files[options->num_host_key_files++] =
154 _PATH_HOST_DSA_KEY_FILE;
157 if (options->num_ports == 0)
158 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
159 if (options->listen_addrs == NULL)
160 add_listen_addr(options, NULL, 0);
161 if (options->pid_file == NULL)
162 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
163 if (options->server_key_bits == -1)
164 options->server_key_bits = 768;
165 if (options->login_grace_time == -1)
166 options->login_grace_time = 600;
167 if (options->key_regeneration_time == -1)
168 options->key_regeneration_time = 3600;
169 if (options->permit_root_login == PERMIT_NOT_SET)
170 options->permit_root_login = PERMIT_YES;
171 if (options->ignore_rhosts == -1)
172 options->ignore_rhosts = 1;
173 if (options->ignore_user_known_hosts == -1)
174 options->ignore_user_known_hosts = 0;
175 if (options->print_motd == -1)
176 options->print_motd = 1;
177 if (options->print_lastlog == -1)
178 options->print_lastlog = 1;
179 if (options->x11_forwarding == -1)
180 options->x11_forwarding = 0;
181 if (options->x11_display_offset == -1)
182 options->x11_display_offset = 10;
183 if (options->x11_use_localhost == -1)
184 options->x11_use_localhost = 1;
185 if (options->xauth_location == NULL)
186 options->xauth_location = _PATH_XAUTH;
187 if (options->strict_modes == -1)
188 options->strict_modes = 1;
189 if (options->keepalives == -1)
190 options->keepalives = 1;
191 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
192 options->log_facility = SYSLOG_FACILITY_AUTH;
193 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
194 options->log_level = SYSLOG_LEVEL_INFO;
195 if (options->rhosts_authentication == -1)
196 options->rhosts_authentication = 0;
197 if (options->rhosts_rsa_authentication == -1)
198 options->rhosts_rsa_authentication = 0;
199 if (options->hostbased_authentication == -1)
200 options->hostbased_authentication = 0;
201 if (options->hostbased_uses_name_from_packet_only == -1)
202 options->hostbased_uses_name_from_packet_only = 0;
203 if (options->rsa_authentication == -1)
204 options->rsa_authentication = 1;
205 if (options->pubkey_authentication == -1)
206 options->pubkey_authentication = 1;
208 if (options->gss_authentication == -1)
209 options->gss_authentication = 1;
210 if (options->gss_keyex == -1)
211 options->gss_keyex =1;
212 if (options->gss_use_session_ccache == -1)
213 options->gss_use_session_ccache = 1;
214 if (options->gss_cleanup_creds == -1)
215 options->gss_cleanup_creds = 1;
217 #if defined(KRB4) || defined(KRB5)
218 if (options->kerberos_authentication == -1)
219 options->kerberos_authentication = 0;
220 if (options->kerberos_or_local_passwd == -1)
221 options->kerberos_or_local_passwd = 1;
222 if (options->kerberos_ticket_cleanup == -1)
223 options->kerberos_ticket_cleanup = 1;
225 #if defined(AFS) || defined(KRB5)
226 if (options->kerberos_tgt_passing == -1)
227 options->kerberos_tgt_passing = 0;
230 if (options->afs_token_passing == -1)
231 options->afs_token_passing = 0;
233 if (options->password_authentication == -1)
234 options->password_authentication = 1;
235 if (options->kbd_interactive_authentication == -1)
236 options->kbd_interactive_authentication = 0;
237 if (options->challenge_response_authentication == -1)
238 options->challenge_response_authentication = 1;
239 if (options->permit_empty_passwd == -1)
240 options->permit_empty_passwd = 0;
241 if (options->use_login == -1)
242 options->use_login = 0;
243 if (options->allow_tcp_forwarding == -1)
244 options->allow_tcp_forwarding = 1;
245 if (options->gateway_ports == -1)
246 options->gateway_ports = 0;
247 if (options->max_startups == -1)
248 options->max_startups = 10;
249 if (options->max_startups_rate == -1)
250 options->max_startups_rate = 100; /* 100% */
251 if (options->max_startups_begin == -1)
252 options->max_startups_begin = options->max_startups;
253 if (options->verify_reverse_mapping == -1)
254 options->verify_reverse_mapping = 0;
255 if (options->client_alive_interval == -1)
256 options->client_alive_interval = 0;
257 if (options->client_alive_count_max == -1)
258 options->client_alive_count_max = 3;
259 if (options->authorized_keys_file2 == NULL) {
260 /* authorized_keys_file2 falls back to authorized_keys_file */
261 if (options->authorized_keys_file != NULL)
262 options->authorized_keys_file2 = options->authorized_keys_file;
264 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
266 if (options->authorized_keys_file == NULL)
267 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
269 /* Turn privilege separation _off_ by default */
270 if (use_privsep == -1)
274 /* Keyword tokens. */
276 sBadOption, /* == unknown option */
277 /* Portable-specific options */
278 sPAMAuthenticationViaKbdInt,
279 /* Standard Options */
280 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
281 sPermitRootLogin, sLogFacility, sLogLevel,
282 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
284 sGssAuthentication, sGssKeyEx, sGssUseSessionCredCache, sGssCleanupCreds,
286 #if defined(KRB4) || defined(KRB5)
287 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
289 #if defined(AFS) || defined(KRB5)
295 sChallengeResponseAuthentication,
296 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
297 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
298 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
299 sStrictModes, sEmptyPasswd, sKeepAlives,
300 sUseLogin, sAllowTcpForwarding,
301 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
302 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
303 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
304 sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
305 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
306 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
307 sUsePrivilegeSeparation,
311 /* Textual representation of the tokens. */
314 ServerOpCodes opcode;
316 /* Portable-specific options */
317 { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
318 /* Standard Options */
320 { "hostkey", sHostKeyFile },
321 { "hostdsakey", sHostKeyFile }, /* alias */
322 { "pidfile", sPidFile },
323 { "serverkeybits", sServerKeyBits },
324 { "logingracetime", sLoginGraceTime },
325 { "keyregenerationinterval", sKeyRegenerationTime },
326 { "permitrootlogin", sPermitRootLogin },
327 { "syslogfacility", sLogFacility },
328 { "loglevel", sLogLevel },
329 { "rhostsauthentication", sRhostsAuthentication },
330 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
331 { "hostbasedauthentication", sHostbasedAuthentication },
332 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
333 { "rsaauthentication", sRSAAuthentication },
334 { "pubkeyauthentication", sPubkeyAuthentication },
335 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
337 { "gssapiauthentication", sGssAuthentication },
338 { "gssapikeyexchange", sGssKeyEx },
339 { "gssusesessionccache", sGssUseSessionCredCache },
340 { "gssapiusesessioncredcache", sGssUseSessionCredCache },
341 { "gssapicleanupcreds", sGssCleanupCreds },
343 #if defined(KRB4) || defined(KRB5)
344 { "kerberosauthentication", sKerberosAuthentication },
345 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
346 { "kerberosticketcleanup", sKerberosTicketCleanup },
348 #if defined(AFS) || defined(KRB5)
349 { "kerberostgtpassing", sKerberosTgtPassing },
352 { "afstokenpassing", sAFSTokenPassing },
354 { "passwordauthentication", sPasswordAuthentication },
355 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
356 { "challengeresponseauthentication", sChallengeResponseAuthentication },
357 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
358 { "checkmail", sDeprecated },
359 { "listenaddress", sListenAddress },
360 { "printmotd", sPrintMotd },
361 { "printlastlog", sPrintLastLog },
362 { "ignorerhosts", sIgnoreRhosts },
363 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
364 { "x11forwarding", sX11Forwarding },
365 { "x11displayoffset", sX11DisplayOffset },
366 { "x11uselocalhost", sX11UseLocalhost },
367 { "xauthlocation", sXAuthLocation },
368 { "strictmodes", sStrictModes },
369 { "permitemptypasswords", sEmptyPasswd },
370 { "uselogin", sUseLogin },
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, "%d", 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;
455 ServerOpCodes opcode;
460 /* Ignore leading whitespace */
463 if (!arg || !*arg || *arg == '#')
467 opcode = parse_token(arg, filename, linenum);
469 /* Portable-specific options */
470 case sPAMAuthenticationViaKbdInt:
471 intptr = &options->pam_authentication_via_kbd_int;
474 /* Standard Options */
478 /* ignore ports from configfile if cmdline specifies ports */
479 if (options->ports_from_cmdline)
481 if (options->listen_addrs != NULL)
482 fatal("%s line %d: ports must be specified before "
483 "ListenAddress.", filename, linenum);
484 if (options->num_ports >= MAX_PORTS)
485 fatal("%s line %d: too many ports.",
488 if (!arg || *arg == '\0')
489 fatal("%s line %d: missing port number.",
491 options->ports[options->num_ports++] = a2port(arg);
492 if (options->ports[options->num_ports-1] == 0)
493 fatal("%s line %d: Badly formatted port number.",
498 intptr = &options->server_key_bits;
501 if (!arg || *arg == '\0')
502 fatal("%s line %d: missing integer value.",
509 case sLoginGraceTime:
510 intptr = &options->login_grace_time;
513 if (!arg || *arg == '\0')
514 fatal("%s line %d: missing time value.",
516 if ((value = convtime(arg)) == -1)
517 fatal("%s line %d: invalid time value.",
523 case sKeyRegenerationTime:
524 intptr = &options->key_regeneration_time;
529 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
530 fatal("%s line %d: missing inet addr.",
533 if ((p = strchr(arg, ']')) == NULL)
534 fatal("%s line %d: bad ipv6 inet addr usage.",
537 memmove(p, p+1, strlen(p+1)+1);
538 } else if (((p = strchr(arg, ':')) == NULL) ||
539 (strchr(p+1, ':') != NULL)) {
540 add_listen_addr(options, arg, 0);
548 fatal("%s line %d: bad inet addr:port usage.",
552 if ((port = a2port(p)) == 0)
553 fatal("%s line %d: bad port number.",
555 add_listen_addr(options, arg, port);
557 } else if (*p == '\0')
558 add_listen_addr(options, arg, 0);
560 fatal("%s line %d: bad inet addr usage.",
565 intptr = &options->num_host_key_files;
566 if (*intptr >= MAX_HOSTKEYS)
567 fatal("%s line %d: too many host keys specified (max %d).",
568 filename, linenum, MAX_HOSTKEYS);
569 charptr = &options->host_key_files[*intptr];
572 if (!arg || *arg == '\0')
573 fatal("%s line %d: missing file name.",
575 if (*charptr == NULL) {
576 *charptr = tilde_expand_filename(arg, getuid());
577 /* increase optional counter */
579 *intptr = *intptr + 1;
584 charptr = &options->pid_file;
587 case sPermitRootLogin:
588 intptr = &options->permit_root_login;
590 if (!arg || *arg == '\0')
591 fatal("%s line %d: missing yes/"
592 "without-password/forced-commands-only/no "
593 "argument.", filename, linenum);
594 value = 0; /* silence compiler */
595 if (strcmp(arg, "without-password") == 0)
596 value = PERMIT_NO_PASSWD;
597 else if (strcmp(arg, "forced-commands-only") == 0)
598 value = PERMIT_FORCED_ONLY;
599 else if (strcmp(arg, "yes") == 0)
601 else if (strcmp(arg, "no") == 0)
604 fatal("%s line %d: Bad yes/"
605 "without-password/forced-commands-only/no "
606 "argument: %s", filename, linenum, arg);
612 intptr = &options->ignore_rhosts;
615 if (!arg || *arg == '\0')
616 fatal("%s line %d: missing yes/no argument.",
618 value = 0; /* silence compiler */
619 if (strcmp(arg, "yes") == 0)
621 else if (strcmp(arg, "no") == 0)
624 fatal("%s line %d: Bad yes/no argument: %s",
625 filename, linenum, arg);
630 case sIgnoreUserKnownHosts:
631 intptr = &options->ignore_user_known_hosts;
634 case sRhostsAuthentication:
635 intptr = &options->rhosts_authentication;
638 case sRhostsRSAAuthentication:
639 intptr = &options->rhosts_rsa_authentication;
642 case sHostbasedAuthentication:
643 intptr = &options->hostbased_authentication;
646 case sHostbasedUsesNameFromPacketOnly:
647 intptr = &options->hostbased_uses_name_from_packet_only;
650 case sRSAAuthentication:
651 intptr = &options->rsa_authentication;
654 case sPubkeyAuthentication:
655 intptr = &options->pubkey_authentication;
658 case sGssAuthentication:
659 intptr = &options->gss_authentication;
662 intptr = &options->gss_keyex;
664 case sGssUseSessionCredCache:
665 intptr = &options->gss_use_session_ccache;
667 case sGssCleanupCreds:
668 intptr = &options->gss_cleanup_creds;
671 #if defined(KRB4) || defined(KRB5)
672 case sKerberosAuthentication:
673 intptr = &options->kerberos_authentication;
676 case sKerberosOrLocalPasswd:
677 intptr = &options->kerberos_or_local_passwd;
680 case sKerberosTicketCleanup:
681 intptr = &options->kerberos_ticket_cleanup;
684 #if defined(AFS) || defined(KRB5)
685 case sKerberosTgtPassing:
686 intptr = &options->kerberos_tgt_passing;
690 case sAFSTokenPassing:
691 intptr = &options->afs_token_passing;
695 case sPasswordAuthentication:
696 intptr = &options->password_authentication;
699 case sKbdInteractiveAuthentication:
700 intptr = &options->kbd_interactive_authentication;
703 case sChallengeResponseAuthentication:
704 intptr = &options->challenge_response_authentication;
708 intptr = &options->print_motd;
712 intptr = &options->print_lastlog;
716 intptr = &options->x11_forwarding;
719 case sX11DisplayOffset:
720 intptr = &options->x11_display_offset;
723 case sX11UseLocalhost:
724 intptr = &options->x11_use_localhost;
728 charptr = &options->xauth_location;
732 intptr = &options->strict_modes;
736 intptr = &options->keepalives;
740 intptr = &options->permit_empty_passwd;
744 intptr = &options->use_login;
748 intptr = &options->gateway_ports;
751 case sVerifyReverseMapping:
752 intptr = &options->verify_reverse_mapping;
756 intptr = (int *) &options->log_facility;
758 value = log_facility_number(arg);
759 if (value == SYSLOG_FACILITY_NOT_SET)
760 fatal("%.200s line %d: unsupported log facility '%s'",
761 filename, linenum, arg ? arg : "<NONE>");
763 *intptr = (SyslogFacility) value;
767 intptr = (int *) &options->log_level;
769 value = log_level_number(arg);
770 if (value == SYSLOG_LEVEL_NOT_SET)
771 fatal("%.200s line %d: unsupported log level '%s'",
772 filename, linenum, arg ? arg : "<NONE>");
774 *intptr = (LogLevel) value;
777 case sAllowTcpForwarding:
778 intptr = &options->allow_tcp_forwarding;
781 case sUsePrivilegeSeparation:
782 intptr = &use_privsep;
786 while ((arg = strdelim(&cp)) && *arg != '\0') {
787 if (options->num_allow_users >= MAX_ALLOW_USERS)
788 fatal("%s line %d: too many allow users.",
790 options->allow_users[options->num_allow_users++] = xstrdup(arg);
795 while ((arg = strdelim(&cp)) && *arg != '\0') {
796 if (options->num_deny_users >= MAX_DENY_USERS)
797 fatal( "%s line %d: too many deny users.",
799 options->deny_users[options->num_deny_users++] = xstrdup(arg);
804 while ((arg = strdelim(&cp)) && *arg != '\0') {
805 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
806 fatal("%s line %d: too many allow groups.",
808 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
813 while ((arg = strdelim(&cp)) && *arg != '\0') {
814 if (options->num_deny_groups >= MAX_DENY_GROUPS)
815 fatal("%s line %d: too many deny groups.",
817 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
823 if (!arg || *arg == '\0')
824 fatal("%s line %d: Missing argument.", filename, linenum);
825 if (!ciphers_valid(arg))
826 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
827 filename, linenum, arg ? arg : "<NONE>");
828 if (options->ciphers == NULL)
829 options->ciphers = xstrdup(arg);
834 if (!arg || *arg == '\0')
835 fatal("%s line %d: Missing argument.", filename, linenum);
837 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
838 filename, linenum, arg ? arg : "<NONE>");
839 if (options->macs == NULL)
840 options->macs = xstrdup(arg);
844 intptr = &options->protocol;
846 if (!arg || *arg == '\0')
847 fatal("%s line %d: Missing argument.", filename, linenum);
848 value = proto_spec(arg);
849 if (value == SSH_PROTO_UNKNOWN)
850 fatal("%s line %d: Bad protocol spec '%s'.",
851 filename, linenum, arg ? arg : "<NONE>");
852 if (*intptr == SSH_PROTO_UNKNOWN)
857 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
858 fatal("%s line %d: too many subsystems defined.",
862 if (!arg || *arg == '\0')
863 fatal("%s line %d: Missing subsystem name.",
865 for (i = 0; i < options->num_subsystems; i++)
866 if (strcmp(arg, options->subsystem_name[i]) == 0)
867 fatal("%s line %d: Subsystem '%s' already defined.",
868 filename, linenum, arg);
869 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
871 if (!arg || *arg == '\0')
872 fatal("%s line %d: Missing subsystem command.",
874 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
875 options->num_subsystems++;
880 if (!arg || *arg == '\0')
881 fatal("%s line %d: Missing MaxStartups spec.",
883 if ((n = sscanf(arg, "%d:%d:%d",
884 &options->max_startups_begin,
885 &options->max_startups_rate,
886 &options->max_startups)) == 3) {
887 if (options->max_startups_begin >
888 options->max_startups ||
889 options->max_startups_rate > 100 ||
890 options->max_startups_rate < 1)
891 fatal("%s line %d: Illegal MaxStartups spec.",
894 fatal("%s line %d: Illegal MaxStartups spec.",
897 options->max_startups = options->max_startups_begin;
901 charptr = &options->banner;
904 * These options can contain %X options expanded at
905 * connect time, so that you can specify paths like:
907 * AuthorizedKeysFile /etc/ssh_keys/%u
909 case sAuthorizedKeysFile:
910 case sAuthorizedKeysFile2:
911 charptr = (opcode == sAuthorizedKeysFile ) ?
912 &options->authorized_keys_file :
913 &options->authorized_keys_file2;
916 case sClientAliveInterval:
917 intptr = &options->client_alive_interval;
920 case sClientAliveCountMax:
921 intptr = &options->client_alive_count_max;
925 log("%s line %d: Deprecated option %s",
926 filename, linenum, arg);
932 fatal("%s line %d: Missing handler for opcode %s (%d)",
933 filename, linenum, arg, opcode);
935 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
936 fatal("%s line %d: garbage at end of line; \"%.200s\".",
937 filename, linenum, arg);
941 /* Reads the server configuration file. */
944 read_server_config(ServerOptions *options, const char *filename)
951 f = fopen(filename, "r");
957 while (fgets(line, sizeof(line), f)) {
958 /* Update line number counter. */
960 if (process_server_config_line(options, line, filename, linenum) != 0)
965 fatal("%s: terminating, %d bad configuration options",
966 filename, bad_options);