1 /* $OpenBSD: servconf.c,v 1.177 2008/02/10 10:54:28 djm Exp $ */
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
15 #include <sys/types.h>
16 #include <sys/socket.h>
33 #include "pathnames.h"
41 #include "groupaccess.h"
43 static void add_listen_addr(ServerOptions *, char *, u_short);
44 static void add_one_listen_addr(ServerOptions *, char *, u_short);
46 /* Use of privilege separation or not */
47 extern int use_privsep;
50 /* Initializes the server options to their default values. */
53 initialize_server_options(ServerOptions *options)
55 memset(options, 0, sizeof(*options));
57 /* Portable-specific options */
58 options->use_pam = -1;
60 /* Standard Options */
61 options->num_ports = 0;
62 options->ports_from_cmdline = 0;
63 options->listen_addrs = NULL;
64 options->address_family = -1;
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->tcp_keep_alive = -1;
81 options->log_facility = SYSLOG_FACILITY_NOT_SET;
82 options->log_level = SYSLOG_LEVEL_NOT_SET;
83 options->rhosts_rsa_authentication = -1;
84 options->hostbased_authentication = -1;
85 options->hostbased_uses_name_from_packet_only = -1;
86 options->rsa_authentication = -1;
87 options->pubkey_authentication = -1;
88 options->kerberos_authentication = -1;
89 options->kerberos_or_local_passwd = -1;
90 options->kerberos_ticket_cleanup = -1;
92 options->session_hooks_allow = -1;
93 options->session_hooks_startup_cmd = NULL;
94 options->session_hooks_shutdown_cmd = NULL;
96 options->kerberos_get_afs_token = -1;
97 options->gss_authentication=-1;
98 options->gss_keyex = -1;
99 options->gss_cleanup_creds = -1;
100 options->gss_strict_acceptor = -1;
101 options->gsi_allow_limited_proxy = -1;
102 options->password_authentication = -1;
103 options->kbd_interactive_authentication = -1;
104 options->challenge_response_authentication = -1;
105 options->permit_empty_passwd = -1;
106 options->permit_user_env = -1;
107 options->use_login = -1;
108 options->compression = -1;
109 options->allow_tcp_forwarding = -1;
110 options->num_allow_users = 0;
111 options->num_deny_users = 0;
112 options->num_allow_groups = 0;
113 options->num_deny_groups = 0;
114 options->ciphers = NULL;
115 options->macs = NULL;
116 options->protocol = SSH_PROTO_UNKNOWN;
117 options->gateway_ports = -1;
118 options->num_subsystems = 0;
119 options->max_startups_begin = -1;
120 options->max_startups_rate = -1;
121 options->max_startups = -1;
122 options->max_authtries = -1;
123 options->banner = NULL;
124 options->use_dns = -1;
125 options->client_alive_interval = -1;
126 options->client_alive_count_max = -1;
127 options->authorized_keys_file = NULL;
128 options->authorized_keys_file2 = NULL;
129 options->num_accept_env = 0;
130 options->permit_tun = -1;
131 options->num_permitted_opens = -1;
132 options->adm_forced_command = NULL;
133 options->chroot_directory = NULL;
134 options->none_enabled = -1;
135 options->tcp_rcv_buf_poll = -1;
136 options->hpn_disabled = -1;
137 options->hpn_buffer_size = -1;
141 fill_default_server_options(ServerOptions *options)
145 int socksizelen = sizeof(int);
147 /* Portable-specific options */
148 if (options->use_pam == -1)
149 options->use_pam = 0;
151 /* Standard Options */
152 if (options->protocol == SSH_PROTO_UNKNOWN)
153 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
154 if (options->num_host_key_files == 0) {
155 /* fill default hostkeys for protocols */
156 if (options->protocol & SSH_PROTO_1)
157 options->host_key_files[options->num_host_key_files++] =
159 if (options->protocol & SSH_PROTO_2) {
160 options->host_key_files[options->num_host_key_files++] =
161 _PATH_HOST_RSA_KEY_FILE;
162 options->host_key_files[options->num_host_key_files++] =
163 _PATH_HOST_DSA_KEY_FILE;
166 if (options->num_ports == 0)
167 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
168 if (options->listen_addrs == NULL)
169 add_listen_addr(options, NULL, 0);
170 if (options->pid_file == NULL)
171 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
172 if (options->server_key_bits == -1)
173 options->server_key_bits = 768;
174 if (options->login_grace_time == -1)
175 options->login_grace_time = 120;
176 if (options->key_regeneration_time == -1)
177 options->key_regeneration_time = 3600;
178 if (options->permit_root_login == PERMIT_NOT_SET)
179 options->permit_root_login = PERMIT_YES;
180 if (options->ignore_rhosts == -1)
181 options->ignore_rhosts = 1;
182 if (options->ignore_user_known_hosts == -1)
183 options->ignore_user_known_hosts = 0;
184 if (options->print_motd == -1)
185 options->print_motd = 1;
186 if (options->print_lastlog == -1)
187 options->print_lastlog = 1;
188 if (options->x11_forwarding == -1)
189 options->x11_forwarding = 0;
190 if (options->x11_display_offset == -1)
191 options->x11_display_offset = 10;
192 if (options->x11_use_localhost == -1)
193 options->x11_use_localhost = 1;
194 if (options->xauth_location == NULL)
195 options->xauth_location = _PATH_XAUTH;
196 if (options->strict_modes == -1)
197 options->strict_modes = 1;
198 if (options->tcp_keep_alive == -1)
199 options->tcp_keep_alive = 1;
200 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
201 options->log_facility = SYSLOG_FACILITY_AUTH;
202 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
203 options->log_level = SYSLOG_LEVEL_INFO;
204 if (options->rhosts_rsa_authentication == -1)
205 options->rhosts_rsa_authentication = 0;
206 if (options->hostbased_authentication == -1)
207 options->hostbased_authentication = 0;
208 if (options->hostbased_uses_name_from_packet_only == -1)
209 options->hostbased_uses_name_from_packet_only = 0;
210 if (options->rsa_authentication == -1)
211 options->rsa_authentication = 1;
212 if (options->pubkey_authentication == -1)
213 options->pubkey_authentication = 1;
214 if (options->kerberos_authentication == -1)
215 options->kerberos_authentication = 0;
216 if (options->kerberos_or_local_passwd == -1)
217 options->kerberos_or_local_passwd = 1;
218 if (options->kerberos_ticket_cleanup == -1)
219 options->kerberos_ticket_cleanup = 1;
220 if (options->kerberos_get_afs_token == -1)
221 options->kerberos_get_afs_token = 0;
222 if (options->gss_authentication == -1)
223 options->gss_authentication = 1;
224 if (options->gss_keyex == -1)
225 options->gss_keyex = 1;
226 if (options->gss_cleanup_creds == -1)
227 options->gss_cleanup_creds = 1;
228 if (options->gss_strict_acceptor == -1)
229 options->gss_strict_acceptor = 1;
230 if (options->gsi_allow_limited_proxy == -1)
231 options->gsi_allow_limited_proxy = 0;
232 if (options->password_authentication == -1)
233 options->password_authentication = 1;
234 if (options->kbd_interactive_authentication == -1)
235 options->kbd_interactive_authentication = 0;
236 if (options->challenge_response_authentication == -1)
237 options->challenge_response_authentication = 1;
238 if (options->permit_empty_passwd == -1)
239 options->permit_empty_passwd = 0;
240 if (options->permit_user_env == -1)
241 options->permit_user_env = 0;
242 if (options->use_login == -1)
243 options->use_login = 0;
244 if (options->compression == -1)
245 options->compression = COMP_DELAYED;
246 if (options->allow_tcp_forwarding == -1)
247 options->allow_tcp_forwarding = 1;
248 if (options->gateway_ports == -1)
249 options->gateway_ports = 0;
250 if (options->max_startups == -1)
251 options->max_startups = 10;
252 if (options->max_startups_rate == -1)
253 options->max_startups_rate = 100; /* 100% */
254 if (options->max_startups_begin == -1)
255 options->max_startups_begin = options->max_startups;
256 if (options->max_authtries == -1)
257 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
258 if (options->use_dns == -1)
259 options->use_dns = 1;
260 if (options->client_alive_interval == -1)
261 options->client_alive_interval = 0;
262 if (options->client_alive_count_max == -1)
263 options->client_alive_count_max = 3;
264 if (options->authorized_keys_file2 == NULL) {
265 /* authorized_keys_file2 falls back to authorized_keys_file */
266 if (options->authorized_keys_file != NULL)
267 options->authorized_keys_file2 = options->authorized_keys_file;
269 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
271 if (options->authorized_keys_file == NULL)
272 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
273 if (options->permit_tun == -1)
274 options->permit_tun = SSH_TUNMODE_NO;
276 if (options->hpn_disabled == -1)
277 options->hpn_disabled = 0;
279 if (options->hpn_buffer_size == -1) {
280 /* option not explicitly set. Now we have to figure out */
281 /* what value to use */
282 if (options->hpn_disabled == 1) {
283 options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
285 /* get the current RCV size and set it to that */
286 /*create a socket but don't connect it */
287 /* we use that the get the rcv socket size */
288 sock = socket(AF_INET, SOCK_STREAM, 0);
289 getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
290 &socksize, &socksizelen);
292 options->hpn_buffer_size = socksize;
293 debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
297 /* we have to do this incase the user sets both values in a contradictory */
298 /* manner. hpn_disabled overrrides hpn_buffer_size*/
299 if (options->hpn_disabled <= 0) {
300 if (options->hpn_buffer_size == 0)
301 options->hpn_buffer_size = 1;
302 /* limit the maximum buffer to 64MB */
303 if (options->hpn_buffer_size > 64*1024) {
304 options->hpn_buffer_size = 64*1024*1024;
306 options->hpn_buffer_size *= 1024;
309 options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
312 /* Turn privilege separation on by default */
313 if (use_privsep == -1)
317 if (use_privsep && options->compression == 1) {
318 error("This platform does not support both privilege "
319 "separation and compression");
320 error("Compression disabled");
321 options->compression = 0;
327 /* Keyword tokens. */
329 sBadOption, /* == unknown option */
330 /* Portable-specific options */
332 /* Standard Options */
333 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
334 sPermitRootLogin, sLogFacility, sLogLevel,
335 sRhostsRSAAuthentication, sRSAAuthentication,
336 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
337 sKerberosGetAFSToken,
338 sKerberosTgtPassing, sChallengeResponseAuthentication,
340 sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
342 sPasswordAuthentication, sKbdInteractiveAuthentication,
343 sListenAddress, sAddressFamily,
344 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
345 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
346 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
347 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
348 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
349 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
350 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
351 sMaxStartups, sMaxAuthTries,
352 sBanner, sUseDNS, sHostbasedAuthentication,
353 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
354 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
355 sGssAuthentication, sGssCleanupCreds,
359 sGsiAllowLimitedProxy,
360 sAcceptEnv, sPermitTunnel,
361 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
362 sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll,
363 sHPNDisabled, sHPNBufferSize,
364 sDeprecated, sUnsupported
367 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
368 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
369 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
371 /* Textual representation of the tokens. */
374 ServerOpCodes opcode;
377 /* Portable-specific options */
379 { "usepam", sUsePAM, SSHCFG_GLOBAL },
381 { "usepam", sUnsupported, SSHCFG_GLOBAL },
383 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
384 /* Standard Options */
385 { "port", sPort, SSHCFG_GLOBAL },
386 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
387 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
388 { "pidfile", sPidFile, SSHCFG_GLOBAL },
389 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
390 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
391 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
392 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
393 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
394 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
395 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
396 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
397 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
398 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
399 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
400 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
401 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
403 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
404 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
405 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
407 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
409 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
412 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
413 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
414 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
415 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
417 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
418 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
420 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
421 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
422 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
423 { "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL },
424 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
426 { "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL },
429 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
430 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
431 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
432 { "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL },
433 { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
435 { "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL },
439 { "allowsessionhooks", sAllowSessionHooks, SSHCFG_GLOBAL },
440 { "sessionhookstartupcmd", sSessionHookStartupCmd, SSHCFG_GLOBAL },
441 { "sessionhookshutdowncmd", sSessionHookShutdownCmd, SSHCFG_GLOBAL },
443 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
444 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
445 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
446 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
447 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
448 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
449 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
450 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
451 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
452 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
453 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
454 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
455 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
456 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
457 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
458 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
459 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
460 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
461 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
462 { "compression", sCompression, SSHCFG_GLOBAL },
463 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
464 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
465 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
466 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
467 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
468 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
469 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
470 { "ciphers", sCiphers, SSHCFG_GLOBAL },
471 { "macs", sMacs, SSHCFG_GLOBAL },
472 { "protocol", sProtocol, SSHCFG_GLOBAL },
473 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
474 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
475 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
476 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
477 { "banner", sBanner, SSHCFG_ALL },
478 { "usedns", sUseDNS, SSHCFG_GLOBAL },
479 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
480 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
481 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
482 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
483 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
484 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
485 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
486 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
487 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
488 { "match", sMatch, SSHCFG_ALL },
489 { "permitopen", sPermitOpen, SSHCFG_ALL },
490 { "forcecommand", sForceCommand, SSHCFG_ALL },
491 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
492 { "noneenabled", sNoneEnabled },
493 { "hpndisabled", sHPNDisabled },
494 { "hpnbuffersize", sHPNBufferSize },
495 { "tcprcvbufpoll", sTcpRcvBufPoll },
496 { NULL, sBadOption, 0 }
500 * Returns the number of the token pointed to by cp or sBadOption.
504 parse_token(const char *cp, const char *filename,
505 int linenum, u_int *flags)
509 for (i = 0; keywords[i].name; i++)
510 if (strcasecmp(cp, keywords[i].name) == 0) {
511 debug ("Config token is %s", keywords[i].name);
512 *flags = keywords[i].flags;
513 return keywords[i].opcode;
516 error("%s: line %d: Bad configuration option: %s",
517 filename, linenum, cp);
522 add_listen_addr(ServerOptions *options, char *addr, u_short port)
526 if (options->num_ports == 0)
527 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
528 if (options->address_family == -1)
529 options->address_family = AF_UNSPEC;
531 for (i = 0; i < options->num_ports; i++)
532 add_one_listen_addr(options, addr, options->ports[i]);
534 add_one_listen_addr(options, addr, port);
538 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
540 struct addrinfo hints, *ai, *aitop;
541 char strport[NI_MAXSERV];
544 memset(&hints, 0, sizeof(hints));
545 hints.ai_family = options->address_family;
546 hints.ai_socktype = SOCK_STREAM;
547 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
548 snprintf(strport, sizeof strport, "%u", port);
549 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
550 fatal("bad addr or host: %s (%s)",
551 addr ? addr : "<NULL>",
552 ssh_gai_strerror(gaierr));
553 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
555 ai->ai_next = options->listen_addrs;
556 options->listen_addrs = aitop;
560 * The strategy for the Match blocks is that the config file is parsed twice.
562 * The first time is at startup. activep is initialized to 1 and the
563 * directives in the global context are processed and acted on. Hitting a
564 * Match directive unsets activep and the directives inside the block are
565 * checked for syntax only.
567 * The second time is after a connection has been established but before
568 * authentication. activep is initialized to 2 and global config directives
569 * are ignored since they have already been processed. If the criteria in a
570 * Match block is met, activep is set and the subsequent directives
571 * processed and actioned until EOF or another Match block unsets it. Any
572 * options set are copied into the main server config.
574 * Potential additions/improvements:
575 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
577 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
578 * Match Address 192.168.0.*
583 * AllowTcpForwarding yes
584 * GatewayPorts clientspecified
587 * - Add a PermittedChannelRequests directive
589 * PermittedChannelRequests session,forwarded-tcpip
593 match_cfg_line_group(const char *grps, int line, const char *user)
597 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
601 * Even if we do not have a user yet, we still need to check for
604 arg = cp = xstrdup(grps);
605 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
606 if (ngrps >= MAX_MATCH_GROUPS) {
607 error("line %d: too many groups in Match Group", line);
611 grplist[ngrps++] = p;
617 if ((pw = getpwnam(user)) == NULL) {
618 debug("Can't match group at line %d because user %.100s does "
619 "not exist", line, user);
620 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
621 debug("Can't Match group because user %.100s not in any group "
622 "at line %d", user, line);
623 } else if (ga_match(grplist, ngrps) != 1) {
624 debug("user %.100s does not match group %.100s at line %d",
627 debug("user %.100s matched group %.100s at line %d", user,
638 match_cfg_line(char **condition, int line, const char *user, const char *host,
642 char *arg, *attrib, *cp = *condition;
646 debug3("checking syntax for 'Match %s'", cp);
648 debug3("checking match for '%s' user %s host %s addr %s", cp,
649 user ? user : "(null)", host ? host : "(null)",
650 address ? address : "(null)");
652 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
653 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
654 error("Missing Match criteria for %s", attrib);
658 if (strcasecmp(attrib, "user") == 0) {
663 if (match_pattern_list(user, arg, len, 0) != 1)
666 debug("user %.100s matched 'User %.100s' at "
667 "line %d", user, arg, line);
668 } else if (strcasecmp(attrib, "group") == 0) {
669 switch (match_cfg_line_group(arg, line, user)) {
675 } else if (strcasecmp(attrib, "host") == 0) {
680 if (match_hostname(host, arg, len) != 1)
683 debug("connection from %.100s matched 'Host "
684 "%.100s' at line %d", host, arg, line);
685 } else if (strcasecmp(attrib, "address") == 0) {
690 if (match_hostname(address, arg, len) != 1)
693 debug("connection from %.100s matched 'Address "
694 "%.100s' at line %d", address, arg, line);
696 error("Unsupported Match attribute %s", attrib);
701 debug3("match %sfound", result ? "" : "not ");
706 #define WHITESPACE " \t\r\n"
709 process_server_config_line(ServerOptions *options, char *line,
710 const char *filename, int linenum, int *activep, const char *user,
711 const char *host, const char *address)
713 char *cp, **charptr, *arg, *p;
714 int cmdline = 0, *intptr, value, n;
715 SyslogFacility *log_facility_ptr;
716 LogLevel *log_level_ptr;
717 ServerOpCodes opcode;
723 if ((arg = strdelim(&cp)) == NULL)
725 /* Ignore leading whitespace */
728 if (!arg || !*arg || *arg == '#')
732 opcode = parse_token(arg, filename, linenum, &flags);
734 if (activep == NULL) { /* We are processing a command line directive */
738 if (*activep && opcode != sMatch)
739 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
740 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
742 fatal("%s line %d: Directive '%s' is not allowed "
743 "within a Match block", filename, linenum, arg);
744 } else { /* this is a directive we have already processed */
752 /* Portable-specific options */
754 intptr = &options->use_pam;
757 /* Standard Options */
761 /* ignore ports from configfile if cmdline specifies ports */
762 if (options->ports_from_cmdline)
764 if (options->listen_addrs != NULL)
765 fatal("%s line %d: ports must be specified before "
766 "ListenAddress.", filename, linenum);
767 if (options->num_ports >= MAX_PORTS)
768 fatal("%s line %d: too many ports.",
771 if (!arg || *arg == '\0')
772 fatal("%s line %d: missing port number.",
774 options->ports[options->num_ports++] = a2port(arg);
775 if (options->ports[options->num_ports-1] == 0)
776 fatal("%s line %d: Badly formatted port number.",
781 intptr = &options->server_key_bits;
784 if (!arg || *arg == '\0')
785 fatal("%s line %d: missing integer value.",
788 if (*activep && *intptr == -1)
792 case sLoginGraceTime:
793 intptr = &options->login_grace_time;
796 if (!arg || *arg == '\0')
797 fatal("%s line %d: missing time value.",
799 if ((value = convtime(arg)) == -1)
800 fatal("%s line %d: invalid time value.",
806 case sKeyRegenerationTime:
807 intptr = &options->key_regeneration_time;
812 if (arg == NULL || *arg == '\0')
813 fatal("%s line %d: missing address",
815 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
816 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
817 && strchr(p+1, ':') != NULL) {
818 add_listen_addr(options, arg, 0);
823 fatal("%s line %d: bad address:port usage",
825 p = cleanhostname(p);
828 else if ((port = a2port(arg)) == 0)
829 fatal("%s line %d: bad port number", filename, linenum);
831 add_listen_addr(options, p, port);
837 if (!arg || *arg == '\0')
838 fatal("%s line %d: missing address family.",
840 intptr = &options->address_family;
841 if (options->listen_addrs != NULL)
842 fatal("%s line %d: address family must be specified before "
843 "ListenAddress.", filename, linenum);
844 if (strcasecmp(arg, "inet") == 0)
846 else if (strcasecmp(arg, "inet6") == 0)
848 else if (strcasecmp(arg, "any") == 0)
851 fatal("%s line %d: unsupported address family \"%s\".",
852 filename, linenum, arg);
858 intptr = &options->num_host_key_files;
859 if (*intptr >= MAX_HOSTKEYS)
860 fatal("%s line %d: too many host keys specified (max %d).",
861 filename, linenum, MAX_HOSTKEYS);
862 charptr = &options->host_key_files[*intptr];
865 if (!arg || *arg == '\0')
866 fatal("%s line %d: missing file name.",
868 if (*activep && *charptr == NULL) {
869 *charptr = tilde_expand_filename(arg, getuid());
870 /* increase optional counter */
872 *intptr = *intptr + 1;
877 charptr = &options->pid_file;
880 case sPermitRootLogin:
881 intptr = &options->permit_root_login;
883 if (!arg || *arg == '\0')
884 fatal("%s line %d: missing yes/"
885 "without-password/forced-commands-only/no "
886 "argument.", filename, linenum);
887 value = 0; /* silence compiler */
888 if (strcmp(arg, "without-password") == 0)
889 value = PERMIT_NO_PASSWD;
890 else if (strcmp(arg, "forced-commands-only") == 0)
891 value = PERMIT_FORCED_ONLY;
892 else if (strcmp(arg, "yes") == 0)
894 else if (strcmp(arg, "no") == 0)
897 fatal("%s line %d: Bad yes/"
898 "without-password/forced-commands-only/no "
899 "argument: %s", filename, linenum, arg);
900 if (*activep && *intptr == -1)
905 intptr = &options->ignore_rhosts;
908 if (!arg || *arg == '\0')
909 fatal("%s line %d: missing yes/no argument.",
911 value = 0; /* silence compiler */
912 if (strcmp(arg, "yes") == 0)
914 else if (strcmp(arg, "no") == 0)
917 fatal("%s line %d: Bad yes/no argument: %s",
918 filename, linenum, arg);
919 if (*activep && *intptr == -1)
924 intptr = &options->none_enabled;
928 intptr = &options->tcp_rcv_buf_poll;
932 intptr = &options->hpn_disabled;
936 intptr = &options->hpn_buffer_size;
939 case sIgnoreUserKnownHosts:
940 intptr = &options->ignore_user_known_hosts;
943 case sRhostsRSAAuthentication:
944 intptr = &options->rhosts_rsa_authentication;
947 case sHostbasedAuthentication:
948 intptr = &options->hostbased_authentication;
951 case sHostbasedUsesNameFromPacketOnly:
952 intptr = &options->hostbased_uses_name_from_packet_only;
955 case sRSAAuthentication:
956 intptr = &options->rsa_authentication;
959 case sPubkeyAuthentication:
960 intptr = &options->pubkey_authentication;
963 case sKerberosAuthentication:
964 intptr = &options->kerberos_authentication;
967 case sKerberosOrLocalPasswd:
968 intptr = &options->kerberos_or_local_passwd;
971 case sKerberosTicketCleanup:
972 intptr = &options->kerberos_ticket_cleanup;
975 case sKerberosGetAFSToken:
976 intptr = &options->kerberos_get_afs_token;
979 case sGssAuthentication:
980 intptr = &options->gss_authentication;
984 intptr = &options->gss_keyex;
987 case sGssCleanupCreds:
988 intptr = &options->gss_cleanup_creds;
991 case sGssStrictAcceptor:
992 intptr = &options->gss_strict_acceptor;
996 charptr = &options->gss_creds_path;
999 case sGsiAllowLimitedProxy:
1000 intptr = &options->gsi_allow_limited_proxy;
1003 #ifdef SESSION_HOOKS
1004 case sAllowSessionHooks:
1005 intptr = &options->session_hooks_allow;
1007 case sSessionHookStartupCmd:
1008 case sSessionHookShutdownCmd:
1009 arg = strdelim(&cp);
1010 if (!arg || *arg == '\0')
1011 fatal("%s line %d: empty session hook command",
1013 if (opcode==sSessionHookStartupCmd)
1014 options->session_hooks_startup_cmd = strdup(arg);
1016 options->session_hooks_shutdown_cmd = strdup(arg);
1020 case sPasswordAuthentication:
1021 intptr = &options->password_authentication;
1024 case sKbdInteractiveAuthentication:
1025 intptr = &options->kbd_interactive_authentication;
1028 case sChallengeResponseAuthentication:
1029 intptr = &options->challenge_response_authentication;
1033 intptr = &options->print_motd;
1037 intptr = &options->print_lastlog;
1040 case sX11Forwarding:
1041 intptr = &options->x11_forwarding;
1044 case sX11DisplayOffset:
1045 intptr = &options->x11_display_offset;
1048 case sX11UseLocalhost:
1049 intptr = &options->x11_use_localhost;
1052 case sXAuthLocation:
1053 charptr = &options->xauth_location;
1054 goto parse_filename;
1057 intptr = &options->strict_modes;
1061 intptr = &options->tcp_keep_alive;
1065 intptr = &options->permit_empty_passwd;
1068 case sPermitUserEnvironment:
1069 intptr = &options->permit_user_env;
1073 intptr = &options->use_login;
1077 intptr = &options->compression;
1078 arg = strdelim(&cp);
1079 if (!arg || *arg == '\0')
1080 fatal("%s line %d: missing yes/no/delayed "
1081 "argument.", filename, linenum);
1082 value = 0; /* silence compiler */
1083 if (strcmp(arg, "delayed") == 0)
1084 value = COMP_DELAYED;
1085 else if (strcmp(arg, "yes") == 0)
1087 else if (strcmp(arg, "no") == 0)
1090 fatal("%s line %d: Bad yes/no/delayed "
1091 "argument: %s", filename, linenum, arg);
1097 intptr = &options->gateway_ports;
1098 arg = strdelim(&cp);
1099 if (!arg || *arg == '\0')
1100 fatal("%s line %d: missing yes/no/clientspecified "
1101 "argument.", filename, linenum);
1102 value = 0; /* silence compiler */
1103 if (strcmp(arg, "clientspecified") == 0)
1105 else if (strcmp(arg, "yes") == 0)
1107 else if (strcmp(arg, "no") == 0)
1110 fatal("%s line %d: Bad yes/no/clientspecified "
1111 "argument: %s", filename, linenum, arg);
1112 if (*activep && *intptr == -1)
1117 intptr = &options->use_dns;
1121 log_facility_ptr = &options->log_facility;
1122 arg = strdelim(&cp);
1123 value = log_facility_number(arg);
1124 if (value == SYSLOG_FACILITY_NOT_SET)
1125 fatal("%.200s line %d: unsupported log facility '%s'",
1126 filename, linenum, arg ? arg : "<NONE>");
1127 if (*log_facility_ptr == -1)
1128 *log_facility_ptr = (SyslogFacility) value;
1132 log_level_ptr = &options->log_level;
1133 arg = strdelim(&cp);
1134 value = log_level_number(arg);
1135 if (value == SYSLOG_LEVEL_NOT_SET)
1136 fatal("%.200s line %d: unsupported log level '%s'",
1137 filename, linenum, arg ? arg : "<NONE>");
1138 if (*log_level_ptr == -1)
1139 *log_level_ptr = (LogLevel) value;
1142 case sAllowTcpForwarding:
1143 intptr = &options->allow_tcp_forwarding;
1146 case sUsePrivilegeSeparation:
1147 intptr = &use_privsep;
1151 while ((arg = strdelim(&cp)) && *arg != '\0') {
1152 if (options->num_allow_users >= MAX_ALLOW_USERS)
1153 fatal("%s line %d: too many allow users.",
1155 options->allow_users[options->num_allow_users++] =
1161 while ((arg = strdelim(&cp)) && *arg != '\0') {
1162 if (options->num_deny_users >= MAX_DENY_USERS)
1163 fatal("%s line %d: too many deny users.",
1165 options->deny_users[options->num_deny_users++] =
1171 while ((arg = strdelim(&cp)) && *arg != '\0') {
1172 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1173 fatal("%s line %d: too many allow groups.",
1175 options->allow_groups[options->num_allow_groups++] =
1181 while ((arg = strdelim(&cp)) && *arg != '\0') {
1182 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1183 fatal("%s line %d: too many deny groups.",
1185 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1190 arg = strdelim(&cp);
1191 if (!arg || *arg == '\0')
1192 fatal("%s line %d: Missing argument.", filename, linenum);
1193 if (!ciphers_valid(arg))
1194 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1195 filename, linenum, arg ? arg : "<NONE>");
1196 if (options->ciphers == NULL)
1197 options->ciphers = xstrdup(arg);
1201 arg = strdelim(&cp);
1202 if (!arg || *arg == '\0')
1203 fatal("%s line %d: Missing argument.", filename, linenum);
1204 if (!mac_valid(arg))
1205 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1206 filename, linenum, arg ? arg : "<NONE>");
1207 if (options->macs == NULL)
1208 options->macs = xstrdup(arg);
1212 intptr = &options->protocol;
1213 arg = strdelim(&cp);
1214 if (!arg || *arg == '\0')
1215 fatal("%s line %d: Missing argument.", filename, linenum);
1216 value = proto_spec(arg);
1217 if (value == SSH_PROTO_UNKNOWN)
1218 fatal("%s line %d: Bad protocol spec '%s'.",
1219 filename, linenum, arg ? arg : "<NONE>");
1220 if (*intptr == SSH_PROTO_UNKNOWN)
1225 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1226 fatal("%s line %d: too many subsystems defined.",
1229 arg = strdelim(&cp);
1230 if (!arg || *arg == '\0')
1231 fatal("%s line %d: Missing subsystem name.",
1234 arg = strdelim(&cp);
1237 for (i = 0; i < options->num_subsystems; i++)
1238 if (strcmp(arg, options->subsystem_name[i]) == 0)
1239 fatal("%s line %d: Subsystem '%s' already defined.",
1240 filename, linenum, arg);
1241 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1242 arg = strdelim(&cp);
1243 if (!arg || *arg == '\0')
1244 fatal("%s line %d: Missing subsystem command.",
1246 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1248 /* Collect arguments (separate to executable) */
1250 len = strlen(p) + 1;
1251 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1252 len += 1 + strlen(arg);
1253 p = xrealloc(p, 1, len);
1254 strlcat(p, " ", len);
1255 strlcat(p, arg, len);
1257 options->subsystem_args[options->num_subsystems] = p;
1258 options->num_subsystems++;
1262 arg = strdelim(&cp);
1263 if (!arg || *arg == '\0')
1264 fatal("%s line %d: Missing MaxStartups spec.",
1266 if ((n = sscanf(arg, "%d:%d:%d",
1267 &options->max_startups_begin,
1268 &options->max_startups_rate,
1269 &options->max_startups)) == 3) {
1270 if (options->max_startups_begin >
1271 options->max_startups ||
1272 options->max_startups_rate > 100 ||
1273 options->max_startups_rate < 1)
1274 fatal("%s line %d: Illegal MaxStartups spec.",
1277 fatal("%s line %d: Illegal MaxStartups spec.",
1280 options->max_startups = options->max_startups_begin;
1284 intptr = &options->max_authtries;
1288 charptr = &options->banner;
1289 goto parse_filename;
1292 * These options can contain %X options expanded at
1293 * connect time, so that you can specify paths like:
1295 * AuthorizedKeysFile /etc/ssh_keys/%u
1297 case sAuthorizedKeysFile:
1298 case sAuthorizedKeysFile2:
1299 charptr = (opcode == sAuthorizedKeysFile) ?
1300 &options->authorized_keys_file :
1301 &options->authorized_keys_file2;
1302 goto parse_filename;
1304 case sClientAliveInterval:
1305 intptr = &options->client_alive_interval;
1308 case sClientAliveCountMax:
1309 intptr = &options->client_alive_count_max;
1313 while ((arg = strdelim(&cp)) && *arg != '\0') {
1314 if (strchr(arg, '=') != NULL)
1315 fatal("%s line %d: Invalid environment name.",
1317 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1318 fatal("%s line %d: too many allow env.",
1322 options->accept_env[options->num_accept_env++] =
1328 intptr = &options->permit_tun;
1329 arg = strdelim(&cp);
1330 if (!arg || *arg == '\0')
1331 fatal("%s line %d: Missing yes/point-to-point/"
1332 "ethernet/no argument.", filename, linenum);
1333 value = 0; /* silence compiler */
1334 if (strcasecmp(arg, "ethernet") == 0)
1335 value = SSH_TUNMODE_ETHERNET;
1336 else if (strcasecmp(arg, "point-to-point") == 0)
1337 value = SSH_TUNMODE_POINTOPOINT;
1338 else if (strcasecmp(arg, "yes") == 0)
1339 value = SSH_TUNMODE_YES;
1340 else if (strcasecmp(arg, "no") == 0)
1341 value = SSH_TUNMODE_NO;
1343 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1344 "no argument: %s", filename, linenum, arg);
1351 fatal("Match directive not supported as a command-line "
1353 value = match_cfg_line(&cp, linenum, user, host, address);
1355 fatal("%s line %d: Bad Match condition", filename,
1361 arg = strdelim(&cp);
1362 if (!arg || *arg == '\0')
1363 fatal("%s line %d: missing PermitOpen specification",
1365 n = options->num_permitted_opens; /* modified later */
1366 if (strcmp(arg, "any") == 0) {
1367 if (*activep && n == -1) {
1368 channel_clear_adm_permitted_opens();
1369 options->num_permitted_opens = 0;
1373 if (*activep && n == -1)
1374 channel_clear_adm_permitted_opens();
1375 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1378 fatal("%s line %d: missing host in PermitOpen",
1380 p = cleanhostname(p);
1381 if (arg == NULL || (port = a2port(arg)) == 0)
1382 fatal("%s line %d: bad port number in "
1383 "PermitOpen", filename, linenum);
1384 if (*activep && n == -1)
1385 options->num_permitted_opens =
1386 channel_add_adm_permitted_opens(p, port);
1392 fatal("%.200s line %d: Missing argument.", filename,
1394 len = strspn(cp, WHITESPACE);
1395 if (*activep && options->adm_forced_command == NULL)
1396 options->adm_forced_command = xstrdup(cp + len);
1399 case sChrootDirectory:
1400 charptr = &options->chroot_directory;
1402 arg = strdelim(&cp);
1403 if (!arg || *arg == '\0')
1404 fatal("%s line %d: missing file name.",
1406 if (*activep && *charptr == NULL)
1407 *charptr = xstrdup(arg);
1411 logit("%s line %d: Deprecated option %s",
1412 filename, linenum, arg);
1414 arg = strdelim(&cp);
1418 logit("%s line %d: Unsupported option %s",
1419 filename, linenum, arg);
1421 arg = strdelim(&cp);
1425 fatal("%s line %d: Missing handler for opcode %s (%d)",
1426 filename, linenum, arg, opcode);
1428 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1429 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1430 filename, linenum, arg);
1434 /* Reads the server configuration file. */
1437 load_server_config(const char *filename, Buffer *conf)
1439 char line[1024], *cp;
1442 debug2("%s: filename %s", __func__, filename);
1443 if ((f = fopen(filename, "r")) == NULL) {
1448 while (fgets(line, sizeof(line), f)) {
1450 * Trim out comments and strip whitespace
1451 * NB - preserve newlines, they are needed to reproduce
1452 * line numbers later for error messages
1454 if ((cp = strchr(line, '#')) != NULL)
1455 memcpy(cp, "\n", 2);
1456 cp = line + strspn(line, " \t\r");
1458 buffer_append(conf, cp, strlen(cp));
1460 buffer_append(conf, "\0", 1);
1462 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1466 parse_server_match_config(ServerOptions *options, const char *user,
1467 const char *host, const char *address)
1471 initialize_server_options(&mo);
1472 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1473 copy_set_server_options(options, &mo, 0);
1477 #define M_CP_INTOPT(n) do {\
1481 #define M_CP_STROPT(n) do {\
1482 if (src->n != NULL) { \
1483 if (dst->n != NULL) \
1490 * Copy any supported values that are set.
1492 * If the preauth flag is set, we do not bother copying the the string or
1493 * array values that are not used pre-authentication, because any that we
1494 * do use must be explictly sent in mm_getpwnamallow().
1497 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1499 M_CP_INTOPT(password_authentication);
1500 M_CP_INTOPT(gss_authentication);
1501 M_CP_INTOPT(rsa_authentication);
1502 M_CP_INTOPT(pubkey_authentication);
1503 M_CP_INTOPT(kerberos_authentication);
1504 M_CP_INTOPT(hostbased_authentication);
1505 M_CP_INTOPT(kbd_interactive_authentication);
1506 M_CP_INTOPT(permit_root_login);
1508 M_CP_INTOPT(allow_tcp_forwarding);
1509 M_CP_INTOPT(gateway_ports);
1510 M_CP_INTOPT(x11_display_offset);
1511 M_CP_INTOPT(x11_forwarding);
1512 M_CP_INTOPT(x11_use_localhost);
1514 M_CP_STROPT(banner);
1517 M_CP_STROPT(adm_forced_command);
1518 M_CP_STROPT(chroot_directory);
1525 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1526 const char *user, const char *host, const char *address)
1528 int active, linenum, bad_options = 0;
1529 char *cp, *obuf, *cbuf;
1531 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1533 obuf = cbuf = xstrdup(buffer_ptr(conf));
1534 active = user ? 0 : 1;
1536 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1537 if (process_server_config_line(options, cp, filename,
1538 linenum++, &active, user, host, address) != 0)
1542 if (bad_options > 0)
1543 fatal("%s: terminating, %d bad configuration options",
1544 filename, bad_options);