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.140 2005/03/10 22:01:05 deraadt Exp $");
20 #include "pathnames.h"
26 static void add_listen_addr(ServerOptions *, char *, u_short);
27 static void add_one_listen_addr(ServerOptions *, char *, u_short);
29 /* Use of privilege separation or not */
30 extern int use_privsep;
32 /* Initializes the server options to their default values. */
35 initialize_server_options(ServerOptions *options)
37 memset(options, 0, sizeof(*options));
39 /* Portable-specific options */
40 options->use_pam = -1;
42 /* Standard Options */
43 options->num_ports = 0;
44 options->ports_from_cmdline = 0;
45 options->listen_addrs = NULL;
46 options->address_family = -1;
47 options->num_host_key_files = 0;
48 options->pid_file = NULL;
49 options->server_key_bits = -1;
50 options->login_grace_time = -1;
51 options->key_regeneration_time = -1;
52 options->permit_root_login = PERMIT_NOT_SET;
53 options->ignore_rhosts = -1;
54 options->ignore_user_known_hosts = -1;
55 options->print_motd = -1;
56 options->print_lastlog = -1;
57 options->x11_forwarding = -1;
58 options->x11_display_offset = -1;
59 options->x11_use_localhost = -1;
60 options->xauth_location = NULL;
61 options->strict_modes = -1;
62 options->tcp_keep_alive = -1;
63 options->log_facility = SYSLOG_FACILITY_NOT_SET;
64 options->log_level = SYSLOG_LEVEL_NOT_SET;
65 options->rhosts_rsa_authentication = -1;
66 options->hostbased_authentication = -1;
67 options->hostbased_uses_name_from_packet_only = -1;
68 options->rsa_authentication = -1;
69 options->pubkey_authentication = -1;
70 options->kerberos_authentication = -1;
71 options->kerberos_or_local_passwd = -1;
72 options->kerberos_ticket_cleanup = -1;
73 options->kerberos_get_afs_token = -1;
74 options->gss_authentication=-1;
75 options->gss_cleanup_creds = -1;
76 options->password_authentication = -1;
77 options->kbd_interactive_authentication = -1;
78 options->challenge_response_authentication = -1;
79 options->permit_empty_passwd = -1;
80 options->permit_user_env = -1;
81 options->use_login = -1;
82 options->compression = -1;
83 options->allow_tcp_forwarding = -1;
84 options->num_allow_users = 0;
85 options->num_deny_users = 0;
86 options->num_allow_groups = 0;
87 options->num_deny_groups = 0;
88 options->ciphers = NULL;
90 options->protocol = SSH_PROTO_UNKNOWN;
91 options->gateway_ports = -1;
92 options->num_subsystems = 0;
93 options->max_startups_begin = -1;
94 options->max_startups_rate = -1;
95 options->max_startups = -1;
96 options->max_authtries = -1;
97 options->banner = NULL;
98 options->use_dns = -1;
99 options->client_alive_interval = -1;
100 options->client_alive_count_max = -1;
101 options->authorized_keys_file = NULL;
102 options->authorized_keys_file2 = NULL;
103 options->num_accept_env = 0;
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 = 0;
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->tcp_keep_alive == -1)
164 options->tcp_keep_alive = 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_get_afs_token == -1)
186 options->kerberos_get_afs_token = 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->max_authtries == -1)
216 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
217 if (options->use_dns == -1)
218 options->use_dns = 1;
219 if (options->client_alive_interval == -1)
220 options->client_alive_interval = 0;
221 if (options->client_alive_count_max == -1)
222 options->client_alive_count_max = 3;
223 if (options->authorized_keys_file2 == NULL) {
224 /* authorized_keys_file2 falls back to authorized_keys_file */
225 if (options->authorized_keys_file != NULL)
226 options->authorized_keys_file2 = options->authorized_keys_file;
228 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
230 if (options->authorized_keys_file == NULL)
231 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
233 /* Turn privilege separation on by default */
234 if (use_privsep == -1)
238 if (use_privsep && options->compression == 1) {
239 error("This platform does not support both privilege "
240 "separation and compression");
241 error("Compression disabled");
242 options->compression = 0;
248 /* Keyword tokens. */
250 sBadOption, /* == unknown option */
251 /* Portable-specific options */
253 /* Standard Options */
254 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
255 sPermitRootLogin, sLogFacility, sLogLevel,
256 sRhostsRSAAuthentication, sRSAAuthentication,
257 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
258 sKerberosGetAFSToken,
259 sKerberosTgtPassing, sChallengeResponseAuthentication,
260 sPasswordAuthentication, sKbdInteractiveAuthentication,
261 sListenAddress, sAddressFamily,
262 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
263 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
264 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
265 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
266 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
267 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
268 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
269 sMaxStartups, sMaxAuthTries,
270 sBanner, sUseDNS, sHostbasedAuthentication,
271 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
272 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
273 sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
274 sUsePrivilegeSeparation,
275 sDeprecated, sUnsupported
278 /* Textual representation of the tokens. */
281 ServerOpCodes opcode;
283 /* Portable-specific options */
285 { "usepam", sUsePAM },
287 { "usepam", sUnsupported },
289 { "pamauthenticationviakbdint", sDeprecated },
290 /* Standard Options */
292 { "hostkey", sHostKeyFile },
293 { "hostdsakey", sHostKeyFile }, /* alias */
294 { "pidfile", sPidFile },
295 { "serverkeybits", sServerKeyBits },
296 { "logingracetime", sLoginGraceTime },
297 { "keyregenerationinterval", sKeyRegenerationTime },
298 { "permitrootlogin", sPermitRootLogin },
299 { "syslogfacility", sLogFacility },
300 { "loglevel", sLogLevel },
301 { "rhostsauthentication", sDeprecated },
302 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
303 { "hostbasedauthentication", sHostbasedAuthentication },
304 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
305 { "rsaauthentication", sRSAAuthentication },
306 { "pubkeyauthentication", sPubkeyAuthentication },
307 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
309 { "kerberosauthentication", sKerberosAuthentication },
310 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
311 { "kerberosticketcleanup", sKerberosTicketCleanup },
313 { "kerberosgetafstoken", sKerberosGetAFSToken },
315 { "kerberosgetafstoken", sUnsupported },
318 { "kerberosauthentication", sUnsupported },
319 { "kerberosorlocalpasswd", sUnsupported },
320 { "kerberosticketcleanup", sUnsupported },
321 { "kerberosgetafstoken", sUnsupported },
323 { "kerberostgtpassing", sUnsupported },
324 { "afstokenpassing", sUnsupported },
326 { "gssapiauthentication", sGssAuthentication },
327 { "gssapicleanupcredentials", sGssCleanupCreds },
329 { "gssapiauthentication", sUnsupported },
330 { "gssapicleanupcredentials", sUnsupported },
332 { "passwordauthentication", sPasswordAuthentication },
333 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
334 { "challengeresponseauthentication", sChallengeResponseAuthentication },
335 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
336 { "checkmail", sDeprecated },
337 { "listenaddress", sListenAddress },
338 { "addressfamily", sAddressFamily },
339 { "printmotd", sPrintMotd },
340 { "printlastlog", sPrintLastLog },
341 { "ignorerhosts", sIgnoreRhosts },
342 { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
343 { "x11forwarding", sX11Forwarding },
344 { "x11displayoffset", sX11DisplayOffset },
345 { "x11uselocalhost", sX11UseLocalhost },
346 { "xauthlocation", sXAuthLocation },
347 { "strictmodes", sStrictModes },
348 { "permitemptypasswords", sEmptyPasswd },
349 { "permituserenvironment", sPermitUserEnvironment },
350 { "uselogin", sUseLogin },
351 { "compression", sCompression },
352 { "tcpkeepalive", sTCPKeepAlive },
353 { "keepalive", sTCPKeepAlive }, /* obsolete alias */
354 { "allowtcpforwarding", sAllowTcpForwarding },
355 { "allowusers", sAllowUsers },
356 { "denyusers", sDenyUsers },
357 { "allowgroups", sAllowGroups },
358 { "denygroups", sDenyGroups },
359 { "ciphers", sCiphers },
361 { "protocol", sProtocol },
362 { "gatewayports", sGatewayPorts },
363 { "subsystem", sSubsystem },
364 { "maxstartups", sMaxStartups },
365 { "maxauthtries", sMaxAuthTries },
366 { "banner", sBanner },
367 { "usedns", sUseDNS },
368 { "verifyreversemapping", sDeprecated },
369 { "reversemappingcheck", sDeprecated },
370 { "clientaliveinterval", sClientAliveInterval },
371 { "clientalivecountmax", sClientAliveCountMax },
372 { "authorizedkeysfile", sAuthorizedKeysFile },
373 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
374 { "useprivilegeseparation", sUsePrivilegeSeparation},
375 { "acceptenv", sAcceptEnv },
380 * Returns the number of the token pointed to by cp or sBadOption.
384 parse_token(const char *cp, const char *filename,
389 for (i = 0; keywords[i].name; i++)
390 if (strcasecmp(cp, keywords[i].name) == 0)
391 return keywords[i].opcode;
393 error("%s: line %d: Bad configuration option: %s",
394 filename, linenum, cp);
399 add_listen_addr(ServerOptions *options, char *addr, u_short port)
403 if (options->num_ports == 0)
404 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
405 if (options->address_family == -1)
406 options->address_family = AF_UNSPEC;
408 for (i = 0; i < options->num_ports; i++)
409 add_one_listen_addr(options, addr, options->ports[i]);
411 add_one_listen_addr(options, addr, port);
415 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
417 struct addrinfo hints, *ai, *aitop;
418 char strport[NI_MAXSERV];
421 memset(&hints, 0, sizeof(hints));
422 hints.ai_family = options->address_family;
423 hints.ai_socktype = SOCK_STREAM;
424 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
425 snprintf(strport, sizeof strport, "%u", port);
426 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
427 fatal("bad addr or host: %s (%s)",
428 addr ? addr : "<NULL>",
429 gai_strerror(gaierr));
430 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
432 ai->ai_next = options->listen_addrs;
433 options->listen_addrs = aitop;
437 process_server_config_line(ServerOptions *options, char *line,
438 const char *filename, int linenum)
440 char *cp, **charptr, *arg, *p;
441 int *intptr, value, i, n;
442 ServerOpCodes opcode;
447 /* Ignore leading whitespace */
450 if (!arg || !*arg || *arg == '#')
454 opcode = parse_token(arg, filename, linenum);
456 /* Portable-specific options */
458 intptr = &options->use_pam;
461 /* Standard Options */
465 /* ignore ports from configfile if cmdline specifies ports */
466 if (options->ports_from_cmdline)
468 if (options->listen_addrs != NULL)
469 fatal("%s line %d: ports must be specified before "
470 "ListenAddress.", filename, linenum);
471 if (options->num_ports >= MAX_PORTS)
472 fatal("%s line %d: too many ports.",
475 if (!arg || *arg == '\0')
476 fatal("%s line %d: missing port number.",
478 options->ports[options->num_ports++] = a2port(arg);
479 if (options->ports[options->num_ports-1] == 0)
480 fatal("%s line %d: Badly formatted port number.",
485 intptr = &options->server_key_bits;
488 if (!arg || *arg == '\0')
489 fatal("%s line %d: missing integer value.",
496 case sLoginGraceTime:
497 intptr = &options->login_grace_time;
500 if (!arg || *arg == '\0')
501 fatal("%s line %d: missing time value.",
503 if ((value = convtime(arg)) == -1)
504 fatal("%s line %d: invalid time value.",
510 case sKeyRegenerationTime:
511 intptr = &options->key_regeneration_time;
516 if (arg == NULL || *arg == '\0')
517 fatal("%s line %d: missing address",
521 fatal("%s line %d: bad address:port usage",
523 p = cleanhostname(p);
526 else if ((port = a2port(arg)) == 0)
527 fatal("%s line %d: bad port number", filename, linenum);
529 add_listen_addr(options, p, port);
535 intptr = &options->address_family;
536 if (options->listen_addrs != NULL)
537 fatal("%s line %d: address family must be specified before "
538 "ListenAddress.", filename, linenum);
539 if (strcasecmp(arg, "inet") == 0)
541 else if (strcasecmp(arg, "inet6") == 0)
543 else if (strcasecmp(arg, "any") == 0)
546 fatal("%s line %d: unsupported address family \"%s\".",
547 filename, linenum, arg);
553 intptr = &options->num_host_key_files;
554 if (*intptr >= MAX_HOSTKEYS)
555 fatal("%s line %d: too many host keys specified (max %d).",
556 filename, linenum, MAX_HOSTKEYS);
557 charptr = &options->host_key_files[*intptr];
560 if (!arg || *arg == '\0')
561 fatal("%s line %d: missing file name.",
563 if (*charptr == NULL) {
564 *charptr = tilde_expand_filename(arg, getuid());
565 /* increase optional counter */
567 *intptr = *intptr + 1;
572 charptr = &options->pid_file;
575 case sPermitRootLogin:
576 intptr = &options->permit_root_login;
578 if (!arg || *arg == '\0')
579 fatal("%s line %d: missing yes/"
580 "without-password/forced-commands-only/no "
581 "argument.", filename, linenum);
582 value = 0; /* silence compiler */
583 if (strcmp(arg, "without-password") == 0)
584 value = PERMIT_NO_PASSWD;
585 else if (strcmp(arg, "forced-commands-only") == 0)
586 value = PERMIT_FORCED_ONLY;
587 else if (strcmp(arg, "yes") == 0)
589 else if (strcmp(arg, "no") == 0)
592 fatal("%s line %d: Bad yes/"
593 "without-password/forced-commands-only/no "
594 "argument: %s", filename, linenum, arg);
600 intptr = &options->ignore_rhosts;
603 if (!arg || *arg == '\0')
604 fatal("%s line %d: missing yes/no argument.",
606 value = 0; /* silence compiler */
607 if (strcmp(arg, "yes") == 0)
609 else if (strcmp(arg, "no") == 0)
612 fatal("%s line %d: Bad yes/no argument: %s",
613 filename, linenum, arg);
618 case sIgnoreUserKnownHosts:
619 intptr = &options->ignore_user_known_hosts;
622 case sRhostsRSAAuthentication:
623 intptr = &options->rhosts_rsa_authentication;
626 case sHostbasedAuthentication:
627 intptr = &options->hostbased_authentication;
630 case sHostbasedUsesNameFromPacketOnly:
631 intptr = &options->hostbased_uses_name_from_packet_only;
634 case sRSAAuthentication:
635 intptr = &options->rsa_authentication;
638 case sPubkeyAuthentication:
639 intptr = &options->pubkey_authentication;
642 case sKerberosAuthentication:
643 intptr = &options->kerberos_authentication;
646 case sKerberosOrLocalPasswd:
647 intptr = &options->kerberos_or_local_passwd;
650 case sKerberosTicketCleanup:
651 intptr = &options->kerberos_ticket_cleanup;
654 case sKerberosGetAFSToken:
655 intptr = &options->kerberos_get_afs_token;
658 case sGssAuthentication:
659 intptr = &options->gss_authentication;
662 case sGssCleanupCreds:
663 intptr = &options->gss_cleanup_creds;
666 case sPasswordAuthentication:
667 intptr = &options->password_authentication;
670 case sKbdInteractiveAuthentication:
671 intptr = &options->kbd_interactive_authentication;
674 case sChallengeResponseAuthentication:
675 intptr = &options->challenge_response_authentication;
679 intptr = &options->print_motd;
683 intptr = &options->print_lastlog;
687 intptr = &options->x11_forwarding;
690 case sX11DisplayOffset:
691 intptr = &options->x11_display_offset;
694 case sX11UseLocalhost:
695 intptr = &options->x11_use_localhost;
699 charptr = &options->xauth_location;
703 intptr = &options->strict_modes;
707 intptr = &options->tcp_keep_alive;
711 intptr = &options->permit_empty_passwd;
714 case sPermitUserEnvironment:
715 intptr = &options->permit_user_env;
719 intptr = &options->use_login;
723 intptr = &options->compression;
727 intptr = &options->gateway_ports;
729 if (!arg || *arg == '\0')
730 fatal("%s line %d: missing yes/no/clientspecified "
731 "argument.", filename, linenum);
732 value = 0; /* silence compiler */
733 if (strcmp(arg, "clientspecified") == 0)
735 else if (strcmp(arg, "yes") == 0)
737 else if (strcmp(arg, "no") == 0)
740 fatal("%s line %d: Bad yes/no/clientspecified "
741 "argument: %s", filename, linenum, arg);
747 intptr = &options->use_dns;
751 intptr = (int *) &options->log_facility;
753 value = log_facility_number(arg);
754 if (value == SYSLOG_FACILITY_NOT_SET)
755 fatal("%.200s line %d: unsupported log facility '%s'",
756 filename, linenum, arg ? arg : "<NONE>");
758 *intptr = (SyslogFacility) value;
762 intptr = (int *) &options->log_level;
764 value = log_level_number(arg);
765 if (value == SYSLOG_LEVEL_NOT_SET)
766 fatal("%.200s line %d: unsupported log level '%s'",
767 filename, linenum, arg ? arg : "<NONE>");
769 *intptr = (LogLevel) value;
772 case sAllowTcpForwarding:
773 intptr = &options->allow_tcp_forwarding;
776 case sUsePrivilegeSeparation:
777 intptr = &use_privsep;
781 while ((arg = strdelim(&cp)) && *arg != '\0') {
782 if (options->num_allow_users >= MAX_ALLOW_USERS)
783 fatal("%s line %d: too many allow users.",
785 options->allow_users[options->num_allow_users++] =
791 while ((arg = strdelim(&cp)) && *arg != '\0') {
792 if (options->num_deny_users >= MAX_DENY_USERS)
793 fatal( "%s line %d: too many deny users.",
795 options->deny_users[options->num_deny_users++] =
801 while ((arg = strdelim(&cp)) && *arg != '\0') {
802 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
803 fatal("%s line %d: too many allow groups.",
805 options->allow_groups[options->num_allow_groups++] =
811 while ((arg = strdelim(&cp)) && *arg != '\0') {
812 if (options->num_deny_groups >= MAX_DENY_GROUPS)
813 fatal("%s line %d: too many deny groups.",
815 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
821 if (!arg || *arg == '\0')
822 fatal("%s line %d: Missing argument.", filename, linenum);
823 if (!ciphers_valid(arg))
824 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
825 filename, linenum, arg ? arg : "<NONE>");
826 if (options->ciphers == NULL)
827 options->ciphers = xstrdup(arg);
832 if (!arg || *arg == '\0')
833 fatal("%s line %d: Missing argument.", filename, linenum);
835 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
836 filename, linenum, arg ? arg : "<NONE>");
837 if (options->macs == NULL)
838 options->macs = xstrdup(arg);
842 intptr = &options->protocol;
844 if (!arg || *arg == '\0')
845 fatal("%s line %d: Missing argument.", filename, linenum);
846 value = proto_spec(arg);
847 if (value == SSH_PROTO_UNKNOWN)
848 fatal("%s line %d: Bad protocol spec '%s'.",
849 filename, linenum, arg ? arg : "<NONE>");
850 if (*intptr == SSH_PROTO_UNKNOWN)
855 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
856 fatal("%s line %d: too many subsystems defined.",
860 if (!arg || *arg == '\0')
861 fatal("%s line %d: Missing subsystem name.",
863 for (i = 0; i < options->num_subsystems; i++)
864 if (strcmp(arg, options->subsystem_name[i]) == 0)
865 fatal("%s line %d: Subsystem '%s' already defined.",
866 filename, linenum, arg);
867 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
869 if (!arg || *arg == '\0')
870 fatal("%s line %d: Missing subsystem command.",
872 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
873 options->num_subsystems++;
878 if (!arg || *arg == '\0')
879 fatal("%s line %d: Missing MaxStartups spec.",
881 if ((n = sscanf(arg, "%d:%d:%d",
882 &options->max_startups_begin,
883 &options->max_startups_rate,
884 &options->max_startups)) == 3) {
885 if (options->max_startups_begin >
886 options->max_startups ||
887 options->max_startups_rate > 100 ||
888 options->max_startups_rate < 1)
889 fatal("%s line %d: Illegal MaxStartups spec.",
892 fatal("%s line %d: Illegal MaxStartups spec.",
895 options->max_startups = options->max_startups_begin;
899 intptr = &options->max_authtries;
903 charptr = &options->banner;
906 * These options can contain %X options expanded at
907 * connect time, so that you can specify paths like:
909 * AuthorizedKeysFile /etc/ssh_keys/%u
911 case sAuthorizedKeysFile:
912 case sAuthorizedKeysFile2:
913 charptr = (opcode == sAuthorizedKeysFile ) ?
914 &options->authorized_keys_file :
915 &options->authorized_keys_file2;
918 case sClientAliveInterval:
919 intptr = &options->client_alive_interval;
922 case sClientAliveCountMax:
923 intptr = &options->client_alive_count_max;
927 while ((arg = strdelim(&cp)) && *arg != '\0') {
928 if (strchr(arg, '=') != NULL)
929 fatal("%s line %d: Invalid environment name.",
931 if (options->num_accept_env >= MAX_ACCEPT_ENV)
932 fatal("%s line %d: too many allow env.",
934 options->accept_env[options->num_accept_env++] =
940 logit("%s line %d: Deprecated option %s",
941 filename, linenum, arg);
947 logit("%s line %d: Unsupported option %s",
948 filename, linenum, arg);
954 fatal("%s line %d: Missing handler for opcode %s (%d)",
955 filename, linenum, arg, opcode);
957 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
958 fatal("%s line %d: garbage at end of line; \"%.200s\".",
959 filename, linenum, arg);
963 /* Reads the server configuration file. */
966 load_server_config(const char *filename, Buffer *conf)
968 char line[1024], *cp;
971 debug2("%s: filename %s", __func__, filename);
972 if ((f = fopen(filename, "r")) == NULL) {
977 while (fgets(line, sizeof(line), f)) {
979 * Trim out comments and strip whitespace
980 * NB - preserve newlines, they are needed to reproduce
981 * line numbers later for error messages
983 if ((cp = strchr(line, '#')) != NULL)
985 cp = line + strspn(line, " \t\r");
987 buffer_append(conf, cp, strlen(cp));
989 buffer_append(conf, "\0", 1);
991 debug2("%s: done config len = %d", __func__, buffer_len(conf));
995 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
997 int linenum, bad_options = 0;
998 char *cp, *obuf, *cbuf;
1000 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1002 obuf = cbuf = xstrdup(buffer_ptr(conf));
1004 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1005 if (process_server_config_line(options, cp, filename,
1010 if (bad_options > 0)
1011 fatal("%s: terminating, %d bad configuration options",
1012 filename, bad_options);