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_deleg_creds = -1;
99 options->gss_keyex = -1;
100 options->gss_cleanup_creds = -1;
101 options->gss_strict_acceptor = -1;
102 options->gsi_allow_limited_proxy = -1;
103 options->password_authentication = -1;
104 options->kbd_interactive_authentication = -1;
105 options->challenge_response_authentication = -1;
106 options->permit_empty_passwd = -1;
107 options->permit_user_env = -1;
108 options->use_login = -1;
109 options->compression = -1;
110 options->allow_tcp_forwarding = -1;
111 options->num_allow_users = 0;
112 options->num_deny_users = 0;
113 options->num_allow_groups = 0;
114 options->num_deny_groups = 0;
115 options->ciphers = NULL;
116 options->macs = NULL;
117 options->protocol = SSH_PROTO_UNKNOWN;
118 options->gateway_ports = -1;
119 options->num_subsystems = 0;
120 options->max_startups_begin = -1;
121 options->max_startups_rate = -1;
122 options->max_startups = -1;
123 options->max_authtries = -1;
124 options->banner = NULL;
125 options->use_dns = -1;
126 options->client_alive_interval = -1;
127 options->client_alive_count_max = -1;
128 options->authorized_keys_file = NULL;
129 options->authorized_keys_file2 = NULL;
130 options->num_accept_env = 0;
131 options->permit_tun = -1;
132 options->num_permitted_opens = -1;
133 options->adm_forced_command = NULL;
134 options->chroot_directory = NULL;
135 options->none_enabled = -1;
136 options->tcp_rcv_buf_poll = -1;
137 options->hpn_disabled = -1;
138 options->hpn_buffer_size = -1;
142 fill_default_server_options(ServerOptions *options)
146 int socksizelen = sizeof(int);
148 /* Portable-specific options */
149 if (options->use_pam == -1)
150 options->use_pam = 0;
152 /* Standard Options */
153 if (options->protocol == SSH_PROTO_UNKNOWN)
154 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
155 if (options->num_host_key_files == 0) {
156 /* fill default hostkeys for protocols */
157 if (options->protocol & SSH_PROTO_1)
158 options->host_key_files[options->num_host_key_files++] =
160 if (options->protocol & SSH_PROTO_2) {
161 options->host_key_files[options->num_host_key_files++] =
162 _PATH_HOST_RSA_KEY_FILE;
163 options->host_key_files[options->num_host_key_files++] =
164 _PATH_HOST_DSA_KEY_FILE;
167 if (options->num_ports == 0)
168 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
169 if (options->listen_addrs == NULL)
170 add_listen_addr(options, NULL, 0);
171 if (options->pid_file == NULL)
172 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
173 if (options->server_key_bits == -1)
174 options->server_key_bits = 768;
175 if (options->login_grace_time == -1)
176 options->login_grace_time = 120;
177 if (options->key_regeneration_time == -1)
178 options->key_regeneration_time = 3600;
179 if (options->permit_root_login == PERMIT_NOT_SET)
180 options->permit_root_login = PERMIT_YES;
181 if (options->ignore_rhosts == -1)
182 options->ignore_rhosts = 1;
183 if (options->ignore_user_known_hosts == -1)
184 options->ignore_user_known_hosts = 0;
185 if (options->print_motd == -1)
186 options->print_motd = 1;
187 if (options->print_lastlog == -1)
188 options->print_lastlog = 1;
189 if (options->x11_forwarding == -1)
190 options->x11_forwarding = 0;
191 if (options->x11_display_offset == -1)
192 options->x11_display_offset = 10;
193 if (options->x11_use_localhost == -1)
194 options->x11_use_localhost = 1;
195 if (options->xauth_location == NULL)
196 options->xauth_location = _PATH_XAUTH;
197 if (options->strict_modes == -1)
198 options->strict_modes = 1;
199 if (options->tcp_keep_alive == -1)
200 options->tcp_keep_alive = 1;
201 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
202 options->log_facility = SYSLOG_FACILITY_AUTH;
203 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
204 options->log_level = SYSLOG_LEVEL_INFO;
205 if (options->rhosts_rsa_authentication == -1)
206 options->rhosts_rsa_authentication = 0;
207 if (options->hostbased_authentication == -1)
208 options->hostbased_authentication = 0;
209 if (options->hostbased_uses_name_from_packet_only == -1)
210 options->hostbased_uses_name_from_packet_only = 0;
211 if (options->rsa_authentication == -1)
212 options->rsa_authentication = 1;
213 if (options->pubkey_authentication == -1)
214 options->pubkey_authentication = 1;
215 if (options->kerberos_authentication == -1)
216 options->kerberos_authentication = 0;
217 if (options->kerberos_or_local_passwd == -1)
218 options->kerberos_or_local_passwd = 1;
219 if (options->kerberos_ticket_cleanup == -1)
220 options->kerberos_ticket_cleanup = 1;
221 if (options->kerberos_get_afs_token == -1)
222 options->kerberos_get_afs_token = 0;
223 if (options->gss_authentication == -1)
224 options->gss_authentication = 1;
225 if (options->gss_deleg_creds == -1)
226 options->gss_deleg_creds = 1;
227 if (options->gss_keyex == -1)
228 options->gss_keyex = 1;
229 if (options->gss_cleanup_creds == -1)
230 options->gss_cleanup_creds = 1;
231 if (options->gss_strict_acceptor == -1)
232 options->gss_strict_acceptor = 1;
233 if (options->gsi_allow_limited_proxy == -1)
234 options->gsi_allow_limited_proxy = 0;
235 if (options->password_authentication == -1)
236 options->password_authentication = 1;
237 if (options->kbd_interactive_authentication == -1)
238 options->kbd_interactive_authentication = 0;
239 if (options->challenge_response_authentication == -1)
240 options->challenge_response_authentication = 1;
241 if (options->permit_empty_passwd == -1)
242 options->permit_empty_passwd = 0;
243 if (options->permit_user_env == -1)
244 options->permit_user_env = 0;
245 if (options->use_login == -1)
246 options->use_login = 0;
247 if (options->compression == -1)
248 options->compression = COMP_DELAYED;
249 if (options->allow_tcp_forwarding == -1)
250 options->allow_tcp_forwarding = 1;
251 if (options->gateway_ports == -1)
252 options->gateway_ports = 0;
253 if (options->max_startups == -1)
254 options->max_startups = 10;
255 if (options->max_startups_rate == -1)
256 options->max_startups_rate = 100; /* 100% */
257 if (options->max_startups_begin == -1)
258 options->max_startups_begin = options->max_startups;
259 if (options->max_authtries == -1)
260 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
261 if (options->use_dns == -1)
262 options->use_dns = 1;
263 if (options->client_alive_interval == -1)
264 options->client_alive_interval = 0;
265 if (options->client_alive_count_max == -1)
266 options->client_alive_count_max = 3;
267 if (options->authorized_keys_file2 == NULL) {
268 /* authorized_keys_file2 falls back to authorized_keys_file */
269 if (options->authorized_keys_file != NULL)
270 options->authorized_keys_file2 = options->authorized_keys_file;
272 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
274 if (options->authorized_keys_file == NULL)
275 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
276 if (options->permit_tun == -1)
277 options->permit_tun = SSH_TUNMODE_NO;
279 if (options->hpn_disabled == -1)
280 options->hpn_disabled = 0;
282 if (options->hpn_buffer_size == -1) {
283 /* option not explicitly set. Now we have to figure out */
284 /* what value to use */
285 if (options->hpn_disabled == 1) {
286 options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
288 /* get the current RCV size and set it to that */
289 /*create a socket but don't connect it */
290 /* we use that the get the rcv socket size */
291 sock = socket(AF_INET, SOCK_STREAM, 0);
292 getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
293 &socksize, &socksizelen);
295 options->hpn_buffer_size = socksize;
296 debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
300 /* we have to do this incase the user sets both values in a contradictory */
301 /* manner. hpn_disabled overrrides hpn_buffer_size*/
302 if (options->hpn_disabled <= 0) {
303 if (options->hpn_buffer_size == 0)
304 options->hpn_buffer_size = 1;
305 /* limit the maximum buffer to 64MB */
306 if (options->hpn_buffer_size > 64*1024) {
307 options->hpn_buffer_size = 64*1024*1024;
309 options->hpn_buffer_size *= 1024;
312 options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
315 /* Turn privilege separation on by default */
316 if (use_privsep == -1)
320 if (use_privsep && options->compression == 1) {
321 error("This platform does not support both privilege "
322 "separation and compression");
323 error("Compression disabled");
324 options->compression = 0;
330 /* Keyword tokens. */
332 sBadOption, /* == unknown option */
333 /* Portable-specific options */
335 /* Standard Options */
336 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
337 sPermitRootLogin, sLogFacility, sLogLevel,
338 sRhostsRSAAuthentication, sRSAAuthentication,
339 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
340 sKerberosGetAFSToken,
341 sKerberosTgtPassing, sChallengeResponseAuthentication,
343 sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
345 sPasswordAuthentication, sKbdInteractiveAuthentication,
346 sListenAddress, sAddressFamily,
347 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
348 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
349 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
350 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
351 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
352 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
353 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
354 sMaxStartups, sMaxAuthTries,
355 sBanner, sUseDNS, sHostbasedAuthentication,
356 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
357 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
358 sGssAuthentication, sGssCleanupCreds,
363 sGsiAllowLimitedProxy,
364 sAcceptEnv, sPermitTunnel,
365 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
366 sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll,
367 sHPNDisabled, sHPNBufferSize,
368 sDeprecated, sUnsupported
371 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
372 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
373 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
375 /* Textual representation of the tokens. */
378 ServerOpCodes opcode;
381 /* Portable-specific options */
383 { "usepam", sUsePAM, SSHCFG_GLOBAL },
385 { "usepam", sUnsupported, SSHCFG_GLOBAL },
387 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
388 /* Standard Options */
389 { "port", sPort, SSHCFG_GLOBAL },
390 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
391 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
392 { "pidfile", sPidFile, SSHCFG_GLOBAL },
393 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
394 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
395 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
396 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
397 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
398 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
399 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
400 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
401 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
402 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
403 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
404 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
405 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
407 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
408 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
409 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
411 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
413 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
416 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
417 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
418 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
419 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
421 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
422 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
424 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
425 { "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_ALL },
426 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
427 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
428 { "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL },
429 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
431 { "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL },
434 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
435 { "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL },
436 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
437 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
438 { "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL },
439 { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
441 { "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL },
445 { "allowsessionhooks", sAllowSessionHooks, SSHCFG_GLOBAL },
446 { "sessionhookstartupcmd", sSessionHookStartupCmd, SSHCFG_GLOBAL },
447 { "sessionhookshutdowncmd", sSessionHookShutdownCmd, SSHCFG_GLOBAL },
449 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
450 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
451 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
452 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
453 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
454 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
455 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
456 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
457 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
458 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
459 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
460 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
461 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
462 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
463 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
464 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
465 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
466 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
467 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
468 { "compression", sCompression, SSHCFG_GLOBAL },
469 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
470 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
471 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
472 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
473 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
474 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
475 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
476 { "ciphers", sCiphers, SSHCFG_GLOBAL },
477 { "macs", sMacs, SSHCFG_GLOBAL },
478 { "protocol", sProtocol, SSHCFG_GLOBAL },
479 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
480 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
481 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
482 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
483 { "banner", sBanner, SSHCFG_ALL },
484 { "usedns", sUseDNS, SSHCFG_GLOBAL },
485 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
486 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
487 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
488 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
489 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
490 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
491 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
492 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
493 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
494 { "match", sMatch, SSHCFG_ALL },
495 { "permitopen", sPermitOpen, SSHCFG_ALL },
496 { "forcecommand", sForceCommand, SSHCFG_ALL },
497 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
498 { "noneenabled", sNoneEnabled },
499 { "hpndisabled", sHPNDisabled },
500 { "hpnbuffersize", sHPNBufferSize },
501 { "tcprcvbufpoll", sTcpRcvBufPoll },
502 { NULL, sBadOption, 0 }
506 * Returns the number of the token pointed to by cp or sBadOption.
510 parse_token(const char *cp, const char *filename,
511 int linenum, u_int *flags)
515 for (i = 0; keywords[i].name; i++)
516 if (strcasecmp(cp, keywords[i].name) == 0) {
517 debug ("Config token is %s", keywords[i].name);
518 *flags = keywords[i].flags;
519 return keywords[i].opcode;
522 error("%s: line %d: Bad configuration option: %s",
523 filename, linenum, cp);
528 add_listen_addr(ServerOptions *options, char *addr, u_short port)
532 if (options->num_ports == 0)
533 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
534 if (options->address_family == -1)
535 options->address_family = AF_UNSPEC;
537 for (i = 0; i < options->num_ports; i++)
538 add_one_listen_addr(options, addr, options->ports[i]);
540 add_one_listen_addr(options, addr, port);
544 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
546 struct addrinfo hints, *ai, *aitop;
547 char strport[NI_MAXSERV];
550 memset(&hints, 0, sizeof(hints));
551 hints.ai_family = options->address_family;
552 hints.ai_socktype = SOCK_STREAM;
553 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
554 snprintf(strport, sizeof strport, "%u", port);
555 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
556 fatal("bad addr or host: %s (%s)",
557 addr ? addr : "<NULL>",
558 ssh_gai_strerror(gaierr));
559 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
561 ai->ai_next = options->listen_addrs;
562 options->listen_addrs = aitop;
566 * The strategy for the Match blocks is that the config file is parsed twice.
568 * The first time is at startup. activep is initialized to 1 and the
569 * directives in the global context are processed and acted on. Hitting a
570 * Match directive unsets activep and the directives inside the block are
571 * checked for syntax only.
573 * The second time is after a connection has been established but before
574 * authentication. activep is initialized to 2 and global config directives
575 * are ignored since they have already been processed. If the criteria in a
576 * Match block is met, activep is set and the subsequent directives
577 * processed and actioned until EOF or another Match block unsets it. Any
578 * options set are copied into the main server config.
580 * Potential additions/improvements:
581 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
583 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
584 * Match Address 192.168.0.*
589 * AllowTcpForwarding yes
590 * GatewayPorts clientspecified
593 * - Add a PermittedChannelRequests directive
595 * PermittedChannelRequests session,forwarded-tcpip
599 match_cfg_line_group(const char *grps, int line, const char *user)
603 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
607 * Even if we do not have a user yet, we still need to check for
610 arg = cp = xstrdup(grps);
611 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
612 if (ngrps >= MAX_MATCH_GROUPS) {
613 error("line %d: too many groups in Match Group", line);
617 grplist[ngrps++] = p;
623 if ((pw = getpwnam(user)) == NULL) {
624 debug("Can't match group at line %d because user %.100s does "
625 "not exist", line, user);
626 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
627 debug("Can't Match group because user %.100s not in any group "
628 "at line %d", user, line);
629 } else if (ga_match(grplist, ngrps) != 1) {
630 debug("user %.100s does not match group %.100s at line %d",
633 debug("user %.100s matched group %.100s at line %d", user,
644 match_cfg_line(char **condition, int line, const char *user, const char *host,
648 char *arg, *attrib, *cp = *condition;
652 debug3("checking syntax for 'Match %s'", cp);
654 debug3("checking match for '%s' user %s host %s addr %s", cp,
655 user ? user : "(null)", host ? host : "(null)",
656 address ? address : "(null)");
658 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
659 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
660 error("Missing Match criteria for %s", attrib);
664 if (strcasecmp(attrib, "user") == 0) {
669 if (match_pattern_list(user, arg, len, 0) != 1)
672 debug("user %.100s matched 'User %.100s' at "
673 "line %d", user, arg, line);
674 } else if (strcasecmp(attrib, "group") == 0) {
675 switch (match_cfg_line_group(arg, line, user)) {
681 } else if (strcasecmp(attrib, "host") == 0) {
686 if (match_hostname(host, arg, len) != 1)
689 debug("connection from %.100s matched 'Host "
690 "%.100s' at line %d", host, arg, line);
691 } else if (strcasecmp(attrib, "address") == 0) {
696 if (match_hostname(address, arg, len) != 1)
699 debug("connection from %.100s matched 'Address "
700 "%.100s' at line %d", address, arg, line);
702 error("Unsupported Match attribute %s", attrib);
707 debug3("match %sfound", result ? "" : "not ");
712 #define WHITESPACE " \t\r\n"
715 process_server_config_line(ServerOptions *options, char *line,
716 const char *filename, int linenum, int *activep, const char *user,
717 const char *host, const char *address)
719 char *cp, **charptr, *arg, *p;
720 int cmdline = 0, *intptr, value, n;
721 SyslogFacility *log_facility_ptr;
722 LogLevel *log_level_ptr;
723 ServerOpCodes opcode;
729 if ((arg = strdelim(&cp)) == NULL)
731 /* Ignore leading whitespace */
734 if (!arg || !*arg || *arg == '#')
738 opcode = parse_token(arg, filename, linenum, &flags);
740 if (activep == NULL) { /* We are processing a command line directive */
744 if (*activep && opcode != sMatch)
745 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
746 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
748 fatal("%s line %d: Directive '%s' is not allowed "
749 "within a Match block", filename, linenum, arg);
750 } else { /* this is a directive we have already processed */
758 /* Portable-specific options */
760 intptr = &options->use_pam;
763 /* Standard Options */
767 /* ignore ports from configfile if cmdline specifies ports */
768 if (options->ports_from_cmdline)
770 if (options->listen_addrs != NULL)
771 fatal("%s line %d: ports must be specified before "
772 "ListenAddress.", filename, linenum);
773 if (options->num_ports >= MAX_PORTS)
774 fatal("%s line %d: too many ports.",
777 if (!arg || *arg == '\0')
778 fatal("%s line %d: missing port number.",
780 options->ports[options->num_ports++] = a2port(arg);
781 if (options->ports[options->num_ports-1] == 0)
782 fatal("%s line %d: Badly formatted port number.",
787 intptr = &options->server_key_bits;
790 if (!arg || *arg == '\0')
791 fatal("%s line %d: missing integer value.",
794 if (*activep && *intptr == -1)
798 case sLoginGraceTime:
799 intptr = &options->login_grace_time;
802 if (!arg || *arg == '\0')
803 fatal("%s line %d: missing time value.",
805 if ((value = convtime(arg)) == -1)
806 fatal("%s line %d: invalid time value.",
812 case sKeyRegenerationTime:
813 intptr = &options->key_regeneration_time;
818 if (arg == NULL || *arg == '\0')
819 fatal("%s line %d: missing address",
821 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
822 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
823 && strchr(p+1, ':') != NULL) {
824 add_listen_addr(options, arg, 0);
829 fatal("%s line %d: bad address:port usage",
831 p = cleanhostname(p);
834 else if ((port = a2port(arg)) == 0)
835 fatal("%s line %d: bad port number", filename, linenum);
837 add_listen_addr(options, p, port);
843 if (!arg || *arg == '\0')
844 fatal("%s line %d: missing address family.",
846 intptr = &options->address_family;
847 if (options->listen_addrs != NULL)
848 fatal("%s line %d: address family must be specified before "
849 "ListenAddress.", filename, linenum);
850 if (strcasecmp(arg, "inet") == 0)
852 else if (strcasecmp(arg, "inet6") == 0)
854 else if (strcasecmp(arg, "any") == 0)
857 fatal("%s line %d: unsupported address family \"%s\".",
858 filename, linenum, arg);
864 intptr = &options->num_host_key_files;
865 if (*intptr >= MAX_HOSTKEYS)
866 fatal("%s line %d: too many host keys specified (max %d).",
867 filename, linenum, MAX_HOSTKEYS);
868 charptr = &options->host_key_files[*intptr];
871 if (!arg || *arg == '\0')
872 fatal("%s line %d: missing file name.",
874 if (*activep && *charptr == NULL) {
875 *charptr = tilde_expand_filename(arg, getuid());
876 /* increase optional counter */
878 *intptr = *intptr + 1;
883 charptr = &options->pid_file;
886 case sPermitRootLogin:
887 intptr = &options->permit_root_login;
889 if (!arg || *arg == '\0')
890 fatal("%s line %d: missing yes/"
891 "without-password/forced-commands-only/no "
892 "argument.", filename, linenum);
893 value = 0; /* silence compiler */
894 if (strcmp(arg, "without-password") == 0)
895 value = PERMIT_NO_PASSWD;
896 else if (strcmp(arg, "forced-commands-only") == 0)
897 value = PERMIT_FORCED_ONLY;
898 else if (strcmp(arg, "yes") == 0)
900 else if (strcmp(arg, "no") == 0)
903 fatal("%s line %d: Bad yes/"
904 "without-password/forced-commands-only/no "
905 "argument: %s", filename, linenum, arg);
906 if (*activep && *intptr == -1)
911 intptr = &options->ignore_rhosts;
914 if (!arg || *arg == '\0')
915 fatal("%s line %d: missing yes/no argument.",
917 value = 0; /* silence compiler */
918 if (strcmp(arg, "yes") == 0)
920 else if (strcmp(arg, "no") == 0)
923 fatal("%s line %d: Bad yes/no argument: %s",
924 filename, linenum, arg);
925 if (*activep && *intptr == -1)
930 intptr = &options->none_enabled;
934 intptr = &options->tcp_rcv_buf_poll;
938 intptr = &options->hpn_disabled;
942 intptr = &options->hpn_buffer_size;
945 case sIgnoreUserKnownHosts:
946 intptr = &options->ignore_user_known_hosts;
949 case sRhostsRSAAuthentication:
950 intptr = &options->rhosts_rsa_authentication;
953 case sHostbasedAuthentication:
954 intptr = &options->hostbased_authentication;
957 case sHostbasedUsesNameFromPacketOnly:
958 intptr = &options->hostbased_uses_name_from_packet_only;
961 case sRSAAuthentication:
962 intptr = &options->rsa_authentication;
965 case sPubkeyAuthentication:
966 intptr = &options->pubkey_authentication;
969 case sKerberosAuthentication:
970 intptr = &options->kerberos_authentication;
973 case sKerberosOrLocalPasswd:
974 intptr = &options->kerberos_or_local_passwd;
977 case sKerberosTicketCleanup:
978 intptr = &options->kerberos_ticket_cleanup;
981 case sKerberosGetAFSToken:
982 intptr = &options->kerberos_get_afs_token;
985 case sGssAuthentication:
986 intptr = &options->gss_authentication;
989 case sGssDelegateCreds:
990 intptr = &options->gss_deleg_creds;
994 intptr = &options->gss_keyex;
997 case sGssCleanupCreds:
998 intptr = &options->gss_cleanup_creds;
1001 case sGssStrictAcceptor:
1002 intptr = &options->gss_strict_acceptor;
1006 charptr = &options->gss_creds_path;
1007 goto parse_filename;
1009 case sGsiAllowLimitedProxy:
1010 intptr = &options->gsi_allow_limited_proxy;
1013 #ifdef SESSION_HOOKS
1014 case sAllowSessionHooks:
1015 intptr = &options->session_hooks_allow;
1017 case sSessionHookStartupCmd:
1018 case sSessionHookShutdownCmd:
1019 arg = strdelim(&cp);
1020 if (!arg || *arg == '\0')
1021 fatal("%s line %d: empty session hook command",
1023 if (opcode==sSessionHookStartupCmd)
1024 options->session_hooks_startup_cmd = strdup(arg);
1026 options->session_hooks_shutdown_cmd = strdup(arg);
1030 case sPasswordAuthentication:
1031 intptr = &options->password_authentication;
1034 case sKbdInteractiveAuthentication:
1035 intptr = &options->kbd_interactive_authentication;
1038 case sChallengeResponseAuthentication:
1039 intptr = &options->challenge_response_authentication;
1043 intptr = &options->print_motd;
1047 intptr = &options->print_lastlog;
1050 case sX11Forwarding:
1051 intptr = &options->x11_forwarding;
1054 case sX11DisplayOffset:
1055 intptr = &options->x11_display_offset;
1058 case sX11UseLocalhost:
1059 intptr = &options->x11_use_localhost;
1062 case sXAuthLocation:
1063 charptr = &options->xauth_location;
1064 goto parse_filename;
1067 intptr = &options->strict_modes;
1071 intptr = &options->tcp_keep_alive;
1075 intptr = &options->permit_empty_passwd;
1078 case sPermitUserEnvironment:
1079 intptr = &options->permit_user_env;
1083 intptr = &options->use_login;
1087 intptr = &options->compression;
1088 arg = strdelim(&cp);
1089 if (!arg || *arg == '\0')
1090 fatal("%s line %d: missing yes/no/delayed "
1091 "argument.", filename, linenum);
1092 value = 0; /* silence compiler */
1093 if (strcmp(arg, "delayed") == 0)
1094 value = COMP_DELAYED;
1095 else if (strcmp(arg, "yes") == 0)
1097 else if (strcmp(arg, "no") == 0)
1100 fatal("%s line %d: Bad yes/no/delayed "
1101 "argument: %s", filename, linenum, arg);
1107 intptr = &options->gateway_ports;
1108 arg = strdelim(&cp);
1109 if (!arg || *arg == '\0')
1110 fatal("%s line %d: missing yes/no/clientspecified "
1111 "argument.", filename, linenum);
1112 value = 0; /* silence compiler */
1113 if (strcmp(arg, "clientspecified") == 0)
1115 else if (strcmp(arg, "yes") == 0)
1117 else if (strcmp(arg, "no") == 0)
1120 fatal("%s line %d: Bad yes/no/clientspecified "
1121 "argument: %s", filename, linenum, arg);
1122 if (*activep && *intptr == -1)
1127 intptr = &options->use_dns;
1131 log_facility_ptr = &options->log_facility;
1132 arg = strdelim(&cp);
1133 value = log_facility_number(arg);
1134 if (value == SYSLOG_FACILITY_NOT_SET)
1135 fatal("%.200s line %d: unsupported log facility '%s'",
1136 filename, linenum, arg ? arg : "<NONE>");
1137 if (*log_facility_ptr == -1)
1138 *log_facility_ptr = (SyslogFacility) value;
1142 log_level_ptr = &options->log_level;
1143 arg = strdelim(&cp);
1144 value = log_level_number(arg);
1145 if (value == SYSLOG_LEVEL_NOT_SET)
1146 fatal("%.200s line %d: unsupported log level '%s'",
1147 filename, linenum, arg ? arg : "<NONE>");
1148 if (*log_level_ptr == -1)
1149 *log_level_ptr = (LogLevel) value;
1152 case sAllowTcpForwarding:
1153 intptr = &options->allow_tcp_forwarding;
1156 case sUsePrivilegeSeparation:
1157 intptr = &use_privsep;
1161 while ((arg = strdelim(&cp)) && *arg != '\0') {
1162 if (options->num_allow_users >= MAX_ALLOW_USERS)
1163 fatal("%s line %d: too many allow users.",
1165 options->allow_users[options->num_allow_users++] =
1171 while ((arg = strdelim(&cp)) && *arg != '\0') {
1172 if (options->num_deny_users >= MAX_DENY_USERS)
1173 fatal("%s line %d: too many deny users.",
1175 options->deny_users[options->num_deny_users++] =
1181 while ((arg = strdelim(&cp)) && *arg != '\0') {
1182 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1183 fatal("%s line %d: too many allow groups.",
1185 options->allow_groups[options->num_allow_groups++] =
1191 while ((arg = strdelim(&cp)) && *arg != '\0') {
1192 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1193 fatal("%s line %d: too many deny groups.",
1195 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1200 arg = strdelim(&cp);
1201 if (!arg || *arg == '\0')
1202 fatal("%s line %d: Missing argument.", filename, linenum);
1203 if (!ciphers_valid(arg))
1204 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1205 filename, linenum, arg ? arg : "<NONE>");
1206 if (options->ciphers == NULL)
1207 options->ciphers = xstrdup(arg);
1211 arg = strdelim(&cp);
1212 if (!arg || *arg == '\0')
1213 fatal("%s line %d: Missing argument.", filename, linenum);
1214 if (!mac_valid(arg))
1215 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1216 filename, linenum, arg ? arg : "<NONE>");
1217 if (options->macs == NULL)
1218 options->macs = xstrdup(arg);
1222 intptr = &options->protocol;
1223 arg = strdelim(&cp);
1224 if (!arg || *arg == '\0')
1225 fatal("%s line %d: Missing argument.", filename, linenum);
1226 value = proto_spec(arg);
1227 if (value == SSH_PROTO_UNKNOWN)
1228 fatal("%s line %d: Bad protocol spec '%s'.",
1229 filename, linenum, arg ? arg : "<NONE>");
1230 if (*intptr == SSH_PROTO_UNKNOWN)
1235 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1236 fatal("%s line %d: too many subsystems defined.",
1239 arg = strdelim(&cp);
1240 if (!arg || *arg == '\0')
1241 fatal("%s line %d: Missing subsystem name.",
1244 arg = strdelim(&cp);
1247 for (i = 0; i < options->num_subsystems; i++)
1248 if (strcmp(arg, options->subsystem_name[i]) == 0)
1249 fatal("%s line %d: Subsystem '%s' already defined.",
1250 filename, linenum, arg);
1251 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1252 arg = strdelim(&cp);
1253 if (!arg || *arg == '\0')
1254 fatal("%s line %d: Missing subsystem command.",
1256 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1258 /* Collect arguments (separate to executable) */
1260 len = strlen(p) + 1;
1261 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1262 len += 1 + strlen(arg);
1263 p = xrealloc(p, 1, len);
1264 strlcat(p, " ", len);
1265 strlcat(p, arg, len);
1267 options->subsystem_args[options->num_subsystems] = p;
1268 options->num_subsystems++;
1272 arg = strdelim(&cp);
1273 if (!arg || *arg == '\0')
1274 fatal("%s line %d: Missing MaxStartups spec.",
1276 if ((n = sscanf(arg, "%d:%d:%d",
1277 &options->max_startups_begin,
1278 &options->max_startups_rate,
1279 &options->max_startups)) == 3) {
1280 if (options->max_startups_begin >
1281 options->max_startups ||
1282 options->max_startups_rate > 100 ||
1283 options->max_startups_rate < 1)
1284 fatal("%s line %d: Illegal MaxStartups spec.",
1287 fatal("%s line %d: Illegal MaxStartups spec.",
1290 options->max_startups = options->max_startups_begin;
1294 intptr = &options->max_authtries;
1298 charptr = &options->banner;
1299 goto parse_filename;
1302 * These options can contain %X options expanded at
1303 * connect time, so that you can specify paths like:
1305 * AuthorizedKeysFile /etc/ssh_keys/%u
1307 case sAuthorizedKeysFile:
1308 case sAuthorizedKeysFile2:
1309 charptr = (opcode == sAuthorizedKeysFile) ?
1310 &options->authorized_keys_file :
1311 &options->authorized_keys_file2;
1312 goto parse_filename;
1314 case sClientAliveInterval:
1315 intptr = &options->client_alive_interval;
1318 case sClientAliveCountMax:
1319 intptr = &options->client_alive_count_max;
1323 while ((arg = strdelim(&cp)) && *arg != '\0') {
1324 if (strchr(arg, '=') != NULL)
1325 fatal("%s line %d: Invalid environment name.",
1327 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1328 fatal("%s line %d: too many allow env.",
1332 options->accept_env[options->num_accept_env++] =
1338 intptr = &options->permit_tun;
1339 arg = strdelim(&cp);
1340 if (!arg || *arg == '\0')
1341 fatal("%s line %d: Missing yes/point-to-point/"
1342 "ethernet/no argument.", filename, linenum);
1343 value = 0; /* silence compiler */
1344 if (strcasecmp(arg, "ethernet") == 0)
1345 value = SSH_TUNMODE_ETHERNET;
1346 else if (strcasecmp(arg, "point-to-point") == 0)
1347 value = SSH_TUNMODE_POINTOPOINT;
1348 else if (strcasecmp(arg, "yes") == 0)
1349 value = SSH_TUNMODE_YES;
1350 else if (strcasecmp(arg, "no") == 0)
1351 value = SSH_TUNMODE_NO;
1353 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1354 "no argument: %s", filename, linenum, arg);
1361 fatal("Match directive not supported as a command-line "
1363 value = match_cfg_line(&cp, linenum, user, host, address);
1365 fatal("%s line %d: Bad Match condition", filename,
1371 arg = strdelim(&cp);
1372 if (!arg || *arg == '\0')
1373 fatal("%s line %d: missing PermitOpen specification",
1375 n = options->num_permitted_opens; /* modified later */
1376 if (strcmp(arg, "any") == 0) {
1377 if (*activep && n == -1) {
1378 channel_clear_adm_permitted_opens();
1379 options->num_permitted_opens = 0;
1383 if (*activep && n == -1)
1384 channel_clear_adm_permitted_opens();
1385 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1388 fatal("%s line %d: missing host in PermitOpen",
1390 p = cleanhostname(p);
1391 if (arg == NULL || (port = a2port(arg)) == 0)
1392 fatal("%s line %d: bad port number in "
1393 "PermitOpen", filename, linenum);
1394 if (*activep && n == -1)
1395 options->num_permitted_opens =
1396 channel_add_adm_permitted_opens(p, port);
1402 fatal("%.200s line %d: Missing argument.", filename,
1404 len = strspn(cp, WHITESPACE);
1405 if (*activep && options->adm_forced_command == NULL)
1406 options->adm_forced_command = xstrdup(cp + len);
1409 case sChrootDirectory:
1410 charptr = &options->chroot_directory;
1412 arg = strdelim(&cp);
1413 if (!arg || *arg == '\0')
1414 fatal("%s line %d: missing file name.",
1416 if (*activep && *charptr == NULL)
1417 *charptr = xstrdup(arg);
1421 logit("%s line %d: Deprecated option %s",
1422 filename, linenum, arg);
1424 arg = strdelim(&cp);
1428 logit("%s line %d: Unsupported option %s",
1429 filename, linenum, arg);
1431 arg = strdelim(&cp);
1435 fatal("%s line %d: Missing handler for opcode %s (%d)",
1436 filename, linenum, arg, opcode);
1438 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1439 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1440 filename, linenum, arg);
1444 /* Reads the server configuration file. */
1447 load_server_config(const char *filename, Buffer *conf)
1449 char line[1024], *cp;
1452 debug2("%s: filename %s", __func__, filename);
1453 if ((f = fopen(filename, "r")) == NULL) {
1458 while (fgets(line, sizeof(line), f)) {
1460 * Trim out comments and strip whitespace
1461 * NB - preserve newlines, they are needed to reproduce
1462 * line numbers later for error messages
1464 if ((cp = strchr(line, '#')) != NULL)
1465 memcpy(cp, "\n", 2);
1466 cp = line + strspn(line, " \t\r");
1468 buffer_append(conf, cp, strlen(cp));
1470 buffer_append(conf, "\0", 1);
1472 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1476 parse_server_match_config(ServerOptions *options, const char *user,
1477 const char *host, const char *address)
1481 initialize_server_options(&mo);
1482 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1483 copy_set_server_options(options, &mo, 0);
1487 #define M_CP_INTOPT(n) do {\
1491 #define M_CP_STROPT(n) do {\
1492 if (src->n != NULL) { \
1493 if (dst->n != NULL) \
1500 * Copy any supported values that are set.
1502 * If the preauth flag is set, we do not bother copying the the string or
1503 * array values that are not used pre-authentication, because any that we
1504 * do use must be explictly sent in mm_getpwnamallow().
1507 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1509 M_CP_INTOPT(password_authentication);
1510 M_CP_INTOPT(gss_authentication);
1511 M_CP_INTOPT(gss_deleg_creds);
1512 M_CP_INTOPT(rsa_authentication);
1513 M_CP_INTOPT(pubkey_authentication);
1514 M_CP_INTOPT(kerberos_authentication);
1515 M_CP_INTOPT(hostbased_authentication);
1516 M_CP_INTOPT(kbd_interactive_authentication);
1517 M_CP_INTOPT(permit_root_login);
1519 M_CP_INTOPT(allow_tcp_forwarding);
1520 M_CP_INTOPT(gateway_ports);
1521 M_CP_INTOPT(x11_display_offset);
1522 M_CP_INTOPT(x11_forwarding);
1523 M_CP_INTOPT(x11_use_localhost);
1525 M_CP_STROPT(banner);
1528 M_CP_STROPT(adm_forced_command);
1529 M_CP_STROPT(chroot_directory);
1536 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1537 const char *user, const char *host, const char *address)
1539 int active, linenum, bad_options = 0;
1540 char *cp, *obuf, *cbuf;
1542 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1544 obuf = cbuf = xstrdup(buffer_ptr(conf));
1545 active = user ? 0 : 1;
1547 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1548 if (process_server_config_line(options, cp, filename,
1549 linenum++, &active, user, host, address) != 0)
1553 if (bad_options > 0)
1554 fatal("%s: terminating, %d bad configuration options",
1555 filename, bad_options);