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.130 2003/12/23 16:12:10 jakob 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->tcp_keep_alive = -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;
76 options->session_hooks_allow = -1;
77 options->session_hooks_startup_cmd = NULL;
78 options->session_hooks_shutdown_cmd = NULL;
80 options->kerberos_get_afs_token = -1;
81 options->gss_authentication=-1;
82 options->gss_keyex=-1;
83 options->gss_use_session_ccache = -1;
84 options->gss_cleanup_creds = -1;
85 options->password_authentication = -1;
86 options->kbd_interactive_authentication = -1;
87 options->challenge_response_authentication = -1;
88 options->permit_empty_passwd = -1;
89 options->permit_user_env = -1;
90 options->use_login = -1;
91 options->compression = -1;
92 options->allow_tcp_forwarding = -1;
93 options->num_allow_users = 0;
94 options->num_deny_users = 0;
95 options->num_allow_groups = 0;
96 options->num_deny_groups = 0;
97 options->ciphers = NULL;
99 options->protocol = SSH_PROTO_UNKNOWN;
100 options->gateway_ports = -1;
101 options->num_subsystems = 0;
102 options->max_startups_begin = -1;
103 options->max_startups_rate = -1;
104 options->max_startups = -1;
105 options->banner = NULL;
106 options->use_dns = -1;
107 options->client_alive_interval = -1;
108 options->client_alive_count_max = -1;
109 options->authorized_keys_file = NULL;
110 options->authorized_keys_file2 = NULL;
112 /* Needs to be accessable in many places */
117 fill_default_server_options(ServerOptions *options)
119 /* Portable-specific options */
120 if (options->use_pam == -1)
121 options->use_pam = 0;
123 /* Standard Options */
124 if (options->protocol == SSH_PROTO_UNKNOWN)
125 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
126 if (options->num_host_key_files == 0) {
127 /* fill default hostkeys for protocols */
128 if (options->protocol & SSH_PROTO_1)
129 options->host_key_files[options->num_host_key_files++] =
131 if (options->protocol & SSH_PROTO_2) {
132 options->host_key_files[options->num_host_key_files++] =
133 _PATH_HOST_RSA_KEY_FILE;
134 options->host_key_files[options->num_host_key_files++] =
135 _PATH_HOST_DSA_KEY_FILE;
138 if (options->num_ports == 0)
139 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
140 if (options->listen_addrs == NULL)
141 add_listen_addr(options, NULL, 0);
142 if (options->pid_file == NULL)
143 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
144 if (options->server_key_bits == -1)
145 options->server_key_bits = 768;
146 if (options->login_grace_time == -1)
147 options->login_grace_time = 120;
148 if (options->key_regeneration_time == -1)
149 options->key_regeneration_time = 3600;
150 if (options->permit_root_login == PERMIT_NOT_SET)
151 options->permit_root_login = PERMIT_YES;
152 if (options->ignore_rhosts == -1)
153 options->ignore_rhosts = 1;
154 if (options->ignore_user_known_hosts == -1)
155 options->ignore_user_known_hosts = 0;
156 if (options->print_motd == -1)
157 options->print_motd = 1;
158 if (options->print_lastlog == -1)
159 options->print_lastlog = 1;
160 if (options->x11_forwarding == -1)
161 options->x11_forwarding = 0;
162 if (options->x11_display_offset == -1)
163 options->x11_display_offset = 10;
164 if (options->x11_use_localhost == -1)
165 options->x11_use_localhost = 1;
166 if (options->xauth_location == NULL)
167 options->xauth_location = _PATH_XAUTH;
168 if (options->strict_modes == -1)
169 options->strict_modes = 1;
170 if (options->tcp_keep_alive == -1)
171 options->tcp_keep_alive = 1;
172 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
173 options->log_facility = SYSLOG_FACILITY_AUTH;
174 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
175 options->log_level = SYSLOG_LEVEL_INFO;
176 if (options->rhosts_rsa_authentication == -1)
177 options->rhosts_rsa_authentication = 0;
178 if (options->hostbased_authentication == -1)
179 options->hostbased_authentication = 0;
180 if (options->hostbased_uses_name_from_packet_only == -1)
181 options->hostbased_uses_name_from_packet_only = 0;
182 if (options->rsa_authentication == -1)
183 options->rsa_authentication = 1;
184 if (options->pubkey_authentication == -1)
185 options->pubkey_authentication = 1;
186 if (options->kerberos_authentication == -1)
187 options->kerberos_authentication = 0;
188 if (options->kerberos_or_local_passwd == -1)
189 options->kerberos_or_local_passwd = 1;
190 if (options->kerberos_ticket_cleanup == -1)
191 options->kerberos_ticket_cleanup = 1;
192 if (options->kerberos_get_afs_token == -1)
193 options->kerberos_get_afs_token = 0;
194 if (options->gss_authentication == -1)
195 options->gss_authentication = 1;
196 if (options->gss_keyex == -1)
197 options->gss_keyex = 1;
198 if (options->gss_use_session_ccache == -1)
199 options->gss_use_session_ccache = 1;
200 if (options->gss_cleanup_creds == -1)
201 options->gss_cleanup_creds = 1;
202 if (options->password_authentication == -1)
203 options->password_authentication = 1;
204 if (options->kbd_interactive_authentication == -1)
205 options->kbd_interactive_authentication = 0;
206 if (options->challenge_response_authentication == -1)
207 options->challenge_response_authentication = 1;
208 if (options->permit_empty_passwd == -1)
209 options->permit_empty_passwd = 0;
210 if (options->permit_user_env == -1)
211 options->permit_user_env = 0;
212 if (options->use_login == -1)
213 options->use_login = 0;
214 if (options->compression == -1)
215 options->compression = 1;
216 if (options->allow_tcp_forwarding == -1)
217 options->allow_tcp_forwarding = 1;
218 if (options->gateway_ports == -1)
219 options->gateway_ports = 0;
220 if (options->max_startups == -1)
221 options->max_startups = 10;
222 if (options->max_startups_rate == -1)
223 options->max_startups_rate = 100; /* 100% */
224 if (options->max_startups_begin == -1)
225 options->max_startups_begin = options->max_startups;
226 if (options->use_dns == -1)
227 options->use_dns = 1;
228 if (options->client_alive_interval == -1)
229 options->client_alive_interval = 0;
230 if (options->client_alive_count_max == -1)
231 options->client_alive_count_max = 3;
232 if (options->authorized_keys_file2 == NULL) {
233 /* authorized_keys_file2 falls back to authorized_keys_file */
234 if (options->authorized_keys_file != NULL)
235 options->authorized_keys_file2 = options->authorized_keys_file;
237 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
239 if (options->authorized_keys_file == NULL)
240 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
242 /* Turn privilege separation on by default */
243 if (use_privsep == -1)
247 if (use_privsep && options->compression == 1) {
248 error("This platform does not support both privilege "
249 "separation and compression");
250 error("Compression disabled");
251 options->compression = 0;
257 /* Keyword tokens. */
259 sBadOption, /* == unknown option */
260 /* Portable-specific options */
262 /* Standard Options */
263 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
264 sPermitRootLogin, sLogFacility, sLogLevel,
265 sRhostsRSAAuthentication, sRSAAuthentication,
266 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
267 sKerberosGetAFSToken,
268 sKerberosTgtPassing, sChallengeResponseAuthentication,
270 sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
272 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
273 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
274 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
275 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
276 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
277 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
278 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
279 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
280 sBanner, sUseDNS, sHostbasedAuthentication,
281 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
282 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
283 sGssAuthentication, sGssKeyEx, sGssUseSessionCredCache, sGssCleanupCreds,
284 sUsePrivilegeSeparation,
285 sDeprecated, sUnsupported
288 /* Textual representation of the tokens. */
291 ServerOpCodes opcode;
293 /* Portable-specific options */
295 { "usepam", sUsePAM },
297 { "usepam", sUnsupported },
299 { "pamauthenticationviakbdint", sDeprecated },
300 /* Standard Options */
302 { "hostkey", sHostKeyFile },
303 { "hostdsakey", sHostKeyFile }, /* alias */
304 { "pidfile", sPidFile },
305 { "serverkeybits", sServerKeyBits },
306 { "logingracetime", sLoginGraceTime },
307 { "keyregenerationinterval", sKeyRegenerationTime },
308 { "permitrootlogin", sPermitRootLogin },
309 { "syslogfacility", sLogFacility },
310 { "loglevel", sLogLevel },
311 { "rhostsauthentication", sDeprecated },
312 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
313 { "hostbasedauthentication", sHostbasedAuthentication },
314 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
315 { "rsaauthentication", sRSAAuthentication },
316 { "pubkeyauthentication", sPubkeyAuthentication },
317 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
319 { "kerberosauthentication", sKerberosAuthentication },
320 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
321 { "kerberosticketcleanup", sKerberosTicketCleanup },
323 { "kerberosgetafstoken", sKerberosGetAFSToken },
325 { "kerberosgetafstoken", sUnsupported },
328 { "kerberosauthentication", sUnsupported },
329 { "kerberosorlocalpasswd", sUnsupported },
330 { "kerberosticketcleanup", sUnsupported },
331 { "kerberosgetafstoken", sUnsupported },
333 { "kerberostgtpassing", sUnsupported },
334 { "afstokenpassing", sUnsupported },
336 { "gssapiauthentication", sGssAuthentication },
337 { "gssapikeyexchange", sGssKeyEx },
338 { "gssusesessionccache", sGssUseSessionCredCache },
339 { "gssapiusesessioncredcache", sGssUseSessionCredCache },
340 { "gssapicleanupcredentials", sGssCleanupCreds },
342 { "gssapiauthentication", sUnsupported },
343 { "gssapikeyexchange", sUnsupported },
344 { "gssusesessionccache", sUnsupported },
345 { "gssapiusesessioncredcache", sUnsupported },
346 { "gssapicleanupcredentials", sUnsupported },
349 { "allowsessionhooks", sAllowSessionHooks },
350 { "sessionhookstartupcmd", sSessionHookStartupCmd },
351 { "sessionhookshutdowncmd", sSessionHookShutdownCmd },
353 { "passwordauthentication", sPasswordAuthentication },
354 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
355 { "challengeresponseauthentication", sChallengeResponseAuthentication },
356 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
357 { "checkmail", sDeprecated },
358 { "listenaddress", sListenAddress },
359 { "printmotd", sPrintMotd },
360 { "printlastlog", sPrintLastLog },
361 { "ignorerhosts", sIgnoreRhosts },
362 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
363 { "x11forwarding", sX11Forwarding },
364 { "x11displayoffset", sX11DisplayOffset },
365 { "x11uselocalhost", sX11UseLocalhost },
366 { "xauthlocation", sXAuthLocation },
367 { "strictmodes", sStrictModes },
368 { "permitemptypasswords", sEmptyPasswd },
369 { "permituserenvironment", sPermitUserEnvironment },
370 { "uselogin", sUseLogin },
371 { "compression", sCompression },
372 { "tcpkeepalive", sTCPKeepAlive },
373 { "keepalive", sTCPKeepAlive }, /* obsolete alias */
374 { "allowtcpforwarding", sAllowTcpForwarding },
375 { "allowusers", sAllowUsers },
376 { "denyusers", sDenyUsers },
377 { "allowgroups", sAllowGroups },
378 { "denygroups", sDenyGroups },
379 { "ciphers", sCiphers },
381 { "protocol", sProtocol },
382 { "gatewayports", sGatewayPorts },
383 { "subsystem", sSubsystem },
384 { "maxstartups", sMaxStartups },
385 { "banner", sBanner },
386 { "usedns", sUseDNS },
387 { "verifyreversemapping", sDeprecated },
388 { "reversemappingcheck", sDeprecated },
389 { "clientaliveinterval", sClientAliveInterval },
390 { "clientalivecountmax", sClientAliveCountMax },
391 { "authorizedkeysfile", sAuthorizedKeysFile },
392 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
393 { "useprivilegeseparation", sUsePrivilegeSeparation},
398 * Returns the number of the token pointed to by cp or sBadOption.
402 parse_token(const char *cp, const char *filename,
407 for (i = 0; keywords[i].name; i++)
408 if (strcasecmp(cp, keywords[i].name) == 0)
409 return keywords[i].opcode;
411 error("%s: line %d: Bad configuration option: %s",
412 filename, linenum, cp);
417 add_listen_addr(ServerOptions *options, char *addr, u_short port)
421 if (options->num_ports == 0)
422 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
424 for (i = 0; i < options->num_ports; i++)
425 add_one_listen_addr(options, addr, options->ports[i]);
427 add_one_listen_addr(options, addr, port);
431 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
433 struct addrinfo hints, *ai, *aitop;
434 char strport[NI_MAXSERV];
437 memset(&hints, 0, sizeof(hints));
438 hints.ai_family = IPv4or6;
439 hints.ai_socktype = SOCK_STREAM;
440 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
441 snprintf(strport, sizeof strport, "%u", port);
442 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
443 fatal("bad addr or host: %s (%s)",
444 addr ? addr : "<NULL>",
445 gai_strerror(gaierr));
446 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
448 ai->ai_next = options->listen_addrs;
449 options->listen_addrs = aitop;
453 process_server_config_line(ServerOptions *options, char *line,
454 const char *filename, int linenum)
456 char *cp, **charptr, *arg, *p;
457 int *intptr, value, i, n;
458 ServerOpCodes opcode;
462 /* Ignore leading whitespace */
465 if (!arg || !*arg || *arg == '#')
469 opcode = parse_token(arg, filename, linenum);
471 /* Portable-specific options */
473 intptr = &options->use_pam;
476 /* Standard Options */
480 /* ignore ports from configfile if cmdline specifies ports */
481 if (options->ports_from_cmdline)
483 if (options->listen_addrs != NULL)
484 fatal("%s line %d: ports must be specified before "
485 "ListenAddress.", filename, linenum);
486 if (options->num_ports >= MAX_PORTS)
487 fatal("%s line %d: too many ports.",
490 if (!arg || *arg == '\0')
491 fatal("%s line %d: missing port number.",
493 options->ports[options->num_ports++] = a2port(arg);
494 if (options->ports[options->num_ports-1] == 0)
495 fatal("%s line %d: Badly formatted port number.",
500 intptr = &options->server_key_bits;
503 if (!arg || *arg == '\0')
504 fatal("%s line %d: missing integer value.",
511 case sLoginGraceTime:
512 intptr = &options->login_grace_time;
515 if (!arg || *arg == '\0')
516 fatal("%s line %d: missing time value.",
518 if ((value = convtime(arg)) == -1)
519 fatal("%s line %d: invalid time value.",
525 case sKeyRegenerationTime:
526 intptr = &options->key_regeneration_time;
531 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
532 fatal("%s line %d: missing inet addr.",
535 if ((p = strchr(arg, ']')) == NULL)
536 fatal("%s line %d: bad ipv6 inet addr usage.",
539 memmove(p, p+1, strlen(p+1)+1);
540 } else if (((p = strchr(arg, ':')) == NULL) ||
541 (strchr(p+1, ':') != NULL)) {
542 add_listen_addr(options, arg, 0);
550 fatal("%s line %d: bad inet addr:port usage.",
554 if ((port = a2port(p)) == 0)
555 fatal("%s line %d: bad port number.",
557 add_listen_addr(options, arg, port);
559 } else if (*p == '\0')
560 add_listen_addr(options, arg, 0);
562 fatal("%s line %d: bad inet addr usage.",
567 intptr = &options->num_host_key_files;
568 if (*intptr >= MAX_HOSTKEYS)
569 fatal("%s line %d: too many host keys specified (max %d).",
570 filename, linenum, MAX_HOSTKEYS);
571 charptr = &options->host_key_files[*intptr];
574 if (!arg || *arg == '\0')
575 fatal("%s line %d: missing file name.",
577 if (*charptr == NULL) {
578 *charptr = tilde_expand_filename(arg, getuid());
579 /* increase optional counter */
581 *intptr = *intptr + 1;
586 charptr = &options->pid_file;
589 case sPermitRootLogin:
590 intptr = &options->permit_root_login;
592 if (!arg || *arg == '\0')
593 fatal("%s line %d: missing yes/"
594 "without-password/forced-commands-only/no "
595 "argument.", filename, linenum);
596 value = 0; /* silence compiler */
597 if (strcmp(arg, "without-password") == 0)
598 value = PERMIT_NO_PASSWD;
599 else if (strcmp(arg, "forced-commands-only") == 0)
600 value = PERMIT_FORCED_ONLY;
601 else if (strcmp(arg, "yes") == 0)
603 else if (strcmp(arg, "no") == 0)
606 fatal("%s line %d: Bad yes/"
607 "without-password/forced-commands-only/no "
608 "argument: %s", filename, linenum, arg);
614 intptr = &options->ignore_rhosts;
617 if (!arg || *arg == '\0')
618 fatal("%s line %d: missing yes/no argument.",
620 value = 0; /* silence compiler */
621 if (strcmp(arg, "yes") == 0)
623 else if (strcmp(arg, "no") == 0)
626 fatal("%s line %d: Bad yes/no argument: %s",
627 filename, linenum, arg);
632 case sIgnoreUserKnownHosts:
633 intptr = &options->ignore_user_known_hosts;
636 case sRhostsRSAAuthentication:
637 intptr = &options->rhosts_rsa_authentication;
640 case sHostbasedAuthentication:
641 intptr = &options->hostbased_authentication;
644 case sHostbasedUsesNameFromPacketOnly:
645 intptr = &options->hostbased_uses_name_from_packet_only;
648 case sRSAAuthentication:
649 intptr = &options->rsa_authentication;
652 case sPubkeyAuthentication:
653 intptr = &options->pubkey_authentication;
656 case sKerberosAuthentication:
657 intptr = &options->kerberos_authentication;
660 case sKerberosOrLocalPasswd:
661 intptr = &options->kerberos_or_local_passwd;
664 case sKerberosTicketCleanup:
665 intptr = &options->kerberos_ticket_cleanup;
668 case sKerberosGetAFSToken:
669 intptr = &options->kerberos_get_afs_token;
672 case sGssAuthentication:
673 intptr = &options->gss_authentication;
677 intptr = &options->gss_keyex;
680 case sGssUseSessionCredCache:
681 intptr = &options->gss_use_session_ccache;
684 case sGssCleanupCreds:
685 intptr = &options->gss_cleanup_creds;
689 case sAllowSessionHooks:
690 intptr = &options->session_hooks_allow;
692 case sSessionHookStartupCmd:
693 case sSessionHookShutdownCmd:
695 if (!arg || *arg == '\0')
696 fatal("%s line %d: empty session hook command",
698 if (opcode==sSessionHookStartupCmd)
699 options->session_hooks_startup_cmd = strdup(arg);
701 options->session_hooks_shutdown_cmd = strdup(arg);
705 case sPasswordAuthentication:
706 intptr = &options->password_authentication;
709 case sKbdInteractiveAuthentication:
710 intptr = &options->kbd_interactive_authentication;
713 case sChallengeResponseAuthentication:
714 intptr = &options->challenge_response_authentication;
718 intptr = &options->print_motd;
722 intptr = &options->print_lastlog;
726 intptr = &options->x11_forwarding;
729 case sX11DisplayOffset:
730 intptr = &options->x11_display_offset;
733 case sX11UseLocalhost:
734 intptr = &options->x11_use_localhost;
738 charptr = &options->xauth_location;
742 intptr = &options->strict_modes;
746 intptr = &options->tcp_keep_alive;
750 intptr = &options->permit_empty_passwd;
753 case sPermitUserEnvironment:
754 intptr = &options->permit_user_env;
758 intptr = &options->use_login;
762 intptr = &options->compression;
766 intptr = &options->gateway_ports;
770 intptr = &options->use_dns;
774 intptr = (int *) &options->log_facility;
776 value = log_facility_number(arg);
777 if (value == SYSLOG_FACILITY_NOT_SET)
778 fatal("%.200s line %d: unsupported log facility '%s'",
779 filename, linenum, arg ? arg : "<NONE>");
781 *intptr = (SyslogFacility) value;
785 intptr = (int *) &options->log_level;
787 value = log_level_number(arg);
788 if (value == SYSLOG_LEVEL_NOT_SET)
789 fatal("%.200s line %d: unsupported log level '%s'",
790 filename, linenum, arg ? arg : "<NONE>");
792 *intptr = (LogLevel) value;
795 case sAllowTcpForwarding:
796 intptr = &options->allow_tcp_forwarding;
799 case sUsePrivilegeSeparation:
800 intptr = &use_privsep;
804 while ((arg = strdelim(&cp)) && *arg != '\0') {
805 if (options->num_allow_users >= MAX_ALLOW_USERS)
806 fatal("%s line %d: too many allow users.",
808 options->allow_users[options->num_allow_users++] =
814 while ((arg = strdelim(&cp)) && *arg != '\0') {
815 if (options->num_deny_users >= MAX_DENY_USERS)
816 fatal( "%s line %d: too many deny users.",
818 options->deny_users[options->num_deny_users++] =
824 while ((arg = strdelim(&cp)) && *arg != '\0') {
825 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
826 fatal("%s line %d: too many allow groups.",
828 options->allow_groups[options->num_allow_groups++] =
834 while ((arg = strdelim(&cp)) && *arg != '\0') {
835 if (options->num_deny_groups >= MAX_DENY_GROUPS)
836 fatal("%s line %d: too many deny groups.",
838 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
844 if (!arg || *arg == '\0')
845 fatal("%s line %d: Missing argument.", filename, linenum);
846 if (!ciphers_valid(arg))
847 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
848 filename, linenum, arg ? arg : "<NONE>");
849 if (options->ciphers == NULL)
850 options->ciphers = xstrdup(arg);
855 if (!arg || *arg == '\0')
856 fatal("%s line %d: Missing argument.", filename, linenum);
858 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
859 filename, linenum, arg ? arg : "<NONE>");
860 if (options->macs == NULL)
861 options->macs = xstrdup(arg);
865 intptr = &options->protocol;
867 if (!arg || *arg == '\0')
868 fatal("%s line %d: Missing argument.", filename, linenum);
869 value = proto_spec(arg);
870 if (value == SSH_PROTO_UNKNOWN)
871 fatal("%s line %d: Bad protocol spec '%s'.",
872 filename, linenum, arg ? arg : "<NONE>");
873 if (*intptr == SSH_PROTO_UNKNOWN)
878 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
879 fatal("%s line %d: too many subsystems defined.",
883 if (!arg || *arg == '\0')
884 fatal("%s line %d: Missing subsystem name.",
886 for (i = 0; i < options->num_subsystems; i++)
887 if (strcmp(arg, options->subsystem_name[i]) == 0)
888 fatal("%s line %d: Subsystem '%s' already defined.",
889 filename, linenum, arg);
890 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
892 if (!arg || *arg == '\0')
893 fatal("%s line %d: Missing subsystem command.",
895 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
896 options->num_subsystems++;
901 if (!arg || *arg == '\0')
902 fatal("%s line %d: Missing MaxStartups spec.",
904 if ((n = sscanf(arg, "%d:%d:%d",
905 &options->max_startups_begin,
906 &options->max_startups_rate,
907 &options->max_startups)) == 3) {
908 if (options->max_startups_begin >
909 options->max_startups ||
910 options->max_startups_rate > 100 ||
911 options->max_startups_rate < 1)
912 fatal("%s line %d: Illegal MaxStartups spec.",
915 fatal("%s line %d: Illegal MaxStartups spec.",
918 options->max_startups = options->max_startups_begin;
922 charptr = &options->banner;
925 * These options can contain %X options expanded at
926 * connect time, so that you can specify paths like:
928 * AuthorizedKeysFile /etc/ssh_keys/%u
930 case sAuthorizedKeysFile:
931 case sAuthorizedKeysFile2:
932 charptr = (opcode == sAuthorizedKeysFile ) ?
933 &options->authorized_keys_file :
934 &options->authorized_keys_file2;
937 case sClientAliveInterval:
938 intptr = &options->client_alive_interval;
941 case sClientAliveCountMax:
942 intptr = &options->client_alive_count_max;
946 logit("%s line %d: Deprecated option %s",
947 filename, linenum, arg);
953 logit("%s line %d: Unsupported option %s",
954 filename, linenum, arg);
960 fatal("%s line %d: Missing handler for opcode %s (%d)",
961 filename, linenum, arg, opcode);
963 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
964 fatal("%s line %d: garbage at end of line; \"%.200s\".",
965 filename, linenum, arg);
969 /* Reads the server configuration file. */
972 read_server_config(ServerOptions *options, const char *filename)
974 int linenum, bad_options = 0;
978 debug2("read_server_config: filename %s", filename);
979 f = fopen(filename, "r");
985 while (fgets(line, sizeof(line), f)) {
986 /* Update line number counter. */
988 if (process_server_config_line(options, line, filename, linenum) != 0)
993 fatal("%s: terminating, %d bad configuration options",
994 filename, bad_options);