1 /* $OpenBSD: servconf.c,v 1.172 2007/04/23 10:15:39 dtucker 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->none_enabled = -1;
134 options->tcp_rcv_buf_poll = -1;
135 options->hpn_disabled = -1;
136 options->hpn_buffer_size = -1;
140 fill_default_server_options(ServerOptions *options)
144 int socksizelen = sizeof(int);
146 /* Portable-specific options */
147 if (options->use_pam == -1)
148 options->use_pam = 0;
150 /* Standard Options */
151 if (options->protocol == SSH_PROTO_UNKNOWN)
152 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
153 if (options->num_host_key_files == 0) {
154 /* fill default hostkeys for protocols */
155 if (options->protocol & SSH_PROTO_1)
156 options->host_key_files[options->num_host_key_files++] =
158 if (options->protocol & SSH_PROTO_2) {
159 options->host_key_files[options->num_host_key_files++] =
160 _PATH_HOST_RSA_KEY_FILE;
161 options->host_key_files[options->num_host_key_files++] =
162 _PATH_HOST_DSA_KEY_FILE;
165 if (options->num_ports == 0)
166 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
167 if (options->listen_addrs == NULL)
168 add_listen_addr(options, NULL, 0);
169 if (options->pid_file == NULL)
170 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
171 if (options->server_key_bits == -1)
172 options->server_key_bits = 768;
173 if (options->login_grace_time == -1)
174 options->login_grace_time = 120;
175 if (options->key_regeneration_time == -1)
176 options->key_regeneration_time = 3600;
177 if (options->permit_root_login == PERMIT_NOT_SET)
178 options->permit_root_login = PERMIT_YES;
179 if (options->ignore_rhosts == -1)
180 options->ignore_rhosts = 1;
181 if (options->ignore_user_known_hosts == -1)
182 options->ignore_user_known_hosts = 0;
183 if (options->print_motd == -1)
184 options->print_motd = 1;
185 if (options->print_lastlog == -1)
186 options->print_lastlog = 1;
187 if (options->x11_forwarding == -1)
188 options->x11_forwarding = 0;
189 if (options->x11_display_offset == -1)
190 options->x11_display_offset = 10;
191 if (options->x11_use_localhost == -1)
192 options->x11_use_localhost = 1;
193 if (options->xauth_location == NULL)
194 options->xauth_location = _PATH_XAUTH;
195 if (options->strict_modes == -1)
196 options->strict_modes = 1;
197 if (options->tcp_keep_alive == -1)
198 options->tcp_keep_alive = 1;
199 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
200 options->log_facility = SYSLOG_FACILITY_AUTH;
201 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
202 options->log_level = SYSLOG_LEVEL_INFO;
203 if (options->rhosts_rsa_authentication == -1)
204 options->rhosts_rsa_authentication = 0;
205 if (options->hostbased_authentication == -1)
206 options->hostbased_authentication = 0;
207 if (options->hostbased_uses_name_from_packet_only == -1)
208 options->hostbased_uses_name_from_packet_only = 0;
209 if (options->rsa_authentication == -1)
210 options->rsa_authentication = 1;
211 if (options->pubkey_authentication == -1)
212 options->pubkey_authentication = 1;
213 if (options->kerberos_authentication == -1)
214 options->kerberos_authentication = 0;
215 if (options->kerberos_or_local_passwd == -1)
216 options->kerberos_or_local_passwd = 1;
217 if (options->kerberos_ticket_cleanup == -1)
218 options->kerberos_ticket_cleanup = 1;
219 if (options->kerberos_get_afs_token == -1)
220 options->kerberos_get_afs_token = 0;
221 if (options->gss_authentication == -1)
222 options->gss_authentication = 1;
223 if (options->gss_keyex == -1)
224 options->gss_keyex = 1;
225 if (options->gss_cleanup_creds == -1)
226 options->gss_cleanup_creds = 1;
227 if (options->gss_strict_acceptor == -1)
228 options->gss_strict_acceptor = 1;
229 if (options->gsi_allow_limited_proxy == -1)
230 options->gsi_allow_limited_proxy = 0;
231 if (options->password_authentication == -1)
232 options->password_authentication = 1;
233 if (options->kbd_interactive_authentication == -1)
234 options->kbd_interactive_authentication = 0;
235 if (options->challenge_response_authentication == -1)
236 options->challenge_response_authentication = 1;
237 if (options->permit_empty_passwd == -1)
238 options->permit_empty_passwd = 0;
239 if (options->permit_user_env == -1)
240 options->permit_user_env = 0;
241 if (options->use_login == -1)
242 options->use_login = 0;
243 if (options->compression == -1)
244 options->compression = COMP_DELAYED;
245 if (options->allow_tcp_forwarding == -1)
246 options->allow_tcp_forwarding = 1;
247 if (options->gateway_ports == -1)
248 options->gateway_ports = 0;
249 if (options->max_startups == -1)
250 options->max_startups = 10;
251 if (options->max_startups_rate == -1)
252 options->max_startups_rate = 100; /* 100% */
253 if (options->max_startups_begin == -1)
254 options->max_startups_begin = options->max_startups;
255 if (options->max_authtries == -1)
256 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
257 if (options->use_dns == -1)
258 options->use_dns = 1;
259 if (options->client_alive_interval == -1)
260 options->client_alive_interval = 0;
261 if (options->client_alive_count_max == -1)
262 options->client_alive_count_max = 3;
263 if (options->authorized_keys_file2 == NULL) {
264 /* authorized_keys_file2 falls back to authorized_keys_file */
265 if (options->authorized_keys_file != NULL)
266 options->authorized_keys_file2 = options->authorized_keys_file;
268 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
270 if (options->authorized_keys_file == NULL)
271 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
272 if (options->permit_tun == -1)
273 options->permit_tun = SSH_TUNMODE_NO;
275 if (options->hpn_disabled == -1)
276 options->hpn_disabled = 0;
278 if (options->hpn_buffer_size == -1) {
279 /* option not explicitly set. Now we have to figure out */
280 /* what value to use */
281 if (options->hpn_disabled == 1) {
282 options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
284 /* get the current RCV size and set it to that */
285 /*create a socket but don't connect it */
286 /* we use that the get the rcv socket size */
287 sock = socket(AF_INET, SOCK_STREAM, 0);
288 getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
289 &socksize, &socksizelen);
291 options->hpn_buffer_size = socksize;
292 debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
296 /* we have to do this incase the user sets both values in a contradictory */
297 /* manner. hpn_disabled overrrides hpn_buffer_size*/
298 if (options->hpn_disabled <= 0) {
299 if (options->hpn_buffer_size == 0)
300 options->hpn_buffer_size = 1;
301 /* limit the maximum buffer to 64MB */
302 if (options->hpn_buffer_size > 64*1024) {
303 options->hpn_buffer_size = 64*1024*1024;
305 options->hpn_buffer_size *= 1024;
308 options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
311 /* Turn privilege separation on by default */
312 if (use_privsep == -1)
316 if (use_privsep && options->compression == 1) {
317 error("This platform does not support both privilege "
318 "separation and compression");
319 error("Compression disabled");
320 options->compression = 0;
326 /* Keyword tokens. */
328 sBadOption, /* == unknown option */
329 /* Portable-specific options */
331 /* Standard Options */
332 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
333 sPermitRootLogin, sLogFacility, sLogLevel,
334 sRhostsRSAAuthentication, sRSAAuthentication,
335 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
336 sKerberosGetAFSToken,
337 sKerberosTgtPassing, sChallengeResponseAuthentication,
339 sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
341 sPasswordAuthentication, sKbdInteractiveAuthentication,
342 sListenAddress, sAddressFamily,
343 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
344 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
345 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
346 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
347 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
348 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
349 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
350 sMaxStartups, sMaxAuthTries,
351 sBanner, sUseDNS, sHostbasedAuthentication,
352 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
353 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
354 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
357 sGsiAllowLimitedProxy,
358 sAcceptEnv, sPermitTunnel,
359 sMatch, sPermitOpen, sForceCommand,
360 sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll,
361 sHPNDisabled, sHPNBufferSize,
362 sDeprecated, sUnsupported
365 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
366 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
367 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
369 /* Textual representation of the tokens. */
372 ServerOpCodes opcode;
375 /* Portable-specific options */
377 { "usepam", sUsePAM, SSHCFG_GLOBAL },
379 { "usepam", sUnsupported, SSHCFG_GLOBAL },
381 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
382 /* Standard Options */
383 { "port", sPort, SSHCFG_GLOBAL },
384 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
385 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
386 { "pidfile", sPidFile, SSHCFG_GLOBAL },
387 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
388 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
389 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
390 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
391 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
392 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
393 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
394 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
395 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
396 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
397 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
398 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
399 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
401 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
402 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
403 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
405 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
407 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
410 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
411 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
412 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
413 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
415 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
416 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
418 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
419 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
420 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
421 { "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL },
422 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
424 { "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL },
427 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
428 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
429 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
430 { "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL },
431 { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
433 { "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL },
437 { "allowsessionhooks", sAllowSessionHooks, SSHCFG_GLOBAL },
438 { "sessionhookstartupcmd", sSessionHookStartupCmd, SSHCFG_GLOBAL },
439 { "sessionhookshutdowncmd", sSessionHookShutdownCmd, SSHCFG_GLOBAL },
441 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
442 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
443 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
444 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
445 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
446 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
447 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
448 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
449 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
450 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
451 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
452 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
453 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
454 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
455 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
456 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
457 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
458 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
459 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
460 { "compression", sCompression, SSHCFG_GLOBAL },
461 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
462 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
463 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
464 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
465 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
466 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
467 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
468 { "ciphers", sCiphers, SSHCFG_GLOBAL },
469 { "macs", sMacs, SSHCFG_GLOBAL },
470 { "protocol", sProtocol, SSHCFG_GLOBAL },
471 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
472 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
473 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
474 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
475 { "banner", sBanner, SSHCFG_ALL },
476 { "usedns", sUseDNS, SSHCFG_GLOBAL },
477 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
478 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
479 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
480 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
481 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
482 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
483 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
484 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
485 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
486 { "match", sMatch, SSHCFG_ALL },
487 { "permitopen", sPermitOpen, SSHCFG_ALL },
488 { "forcecommand", sForceCommand, SSHCFG_ALL },
489 { "noneenabled", sNoneEnabled },
490 { "hpndisabled", sHPNDisabled },
491 { "hpnbuffersize", sHPNBufferSize },
492 { "tcprcvbufpoll", sTcpRcvBufPoll },
493 { NULL, sBadOption, 0 }
497 * Returns the number of the token pointed to by cp or sBadOption.
501 parse_token(const char *cp, const char *filename,
502 int linenum, u_int *flags)
506 for (i = 0; keywords[i].name; i++)
507 if (strcasecmp(cp, keywords[i].name) == 0) {
508 debug ("Config token is %s", keywords[i].name);
509 *flags = keywords[i].flags;
510 return keywords[i].opcode;
513 error("%s: line %d: Bad configuration option: %s",
514 filename, linenum, cp);
519 add_listen_addr(ServerOptions *options, char *addr, u_short port)
523 if (options->num_ports == 0)
524 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
525 if (options->address_family == -1)
526 options->address_family = AF_UNSPEC;
528 for (i = 0; i < options->num_ports; i++)
529 add_one_listen_addr(options, addr, options->ports[i]);
531 add_one_listen_addr(options, addr, port);
535 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
537 struct addrinfo hints, *ai, *aitop;
538 char strport[NI_MAXSERV];
541 memset(&hints, 0, sizeof(hints));
542 hints.ai_family = options->address_family;
543 hints.ai_socktype = SOCK_STREAM;
544 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
545 snprintf(strport, sizeof strport, "%u", port);
546 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
547 fatal("bad addr or host: %s (%s)",
548 addr ? addr : "<NULL>",
549 gai_strerror(gaierr));
550 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
552 ai->ai_next = options->listen_addrs;
553 options->listen_addrs = aitop;
557 * The strategy for the Match blocks is that the config file is parsed twice.
559 * The first time is at startup. activep is initialized to 1 and the
560 * directives in the global context are processed and acted on. Hitting a
561 * Match directive unsets activep and the directives inside the block are
562 * checked for syntax only.
564 * The second time is after a connection has been established but before
565 * authentication. activep is initialized to 2 and global config directives
566 * are ignored since they have already been processed. If the criteria in a
567 * Match block is met, activep is set and the subsequent directives
568 * processed and actioned until EOF or another Match block unsets it. Any
569 * options set are copied into the main server config.
571 * Potential additions/improvements:
572 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
574 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
575 * Match Address 192.168.0.*
580 * AllowTcpForwarding yes
581 * GatewayPorts clientspecified
584 * - Add a PermittedChannelRequests directive
586 * PermittedChannelRequests session,forwarded-tcpip
590 match_cfg_line_group(const char *grps, int line, const char *user)
594 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
598 * Even if we do not have a user yet, we still need to check for
601 arg = cp = xstrdup(grps);
602 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
603 if (ngrps >= MAX_MATCH_GROUPS) {
604 error("line %d: too many groups in Match Group", line);
608 grplist[ngrps++] = p;
614 if ((pw = getpwnam(user)) == NULL) {
615 debug("Can't match group at line %d because user %.100s does "
616 "not exist", line, user);
617 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
618 debug("Can't Match group because user %.100s not in any group "
619 "at line %d", user, line);
620 } else if (ga_match(grplist, ngrps) != 1) {
621 debug("user %.100s does not match group %.100s at line %d",
624 debug("user %.100s matched group %.100s at line %d", user,
635 match_cfg_line(char **condition, int line, const char *user, const char *host,
639 char *arg, *attrib, *cp = *condition;
643 debug3("checking syntax for 'Match %s'", cp);
645 debug3("checking match for '%s' user %s host %s addr %s", cp,
646 user ? user : "(null)", host ? host : "(null)",
647 address ? address : "(null)");
649 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
650 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
651 error("Missing Match criteria for %s", attrib);
655 if (strcasecmp(attrib, "user") == 0) {
660 if (match_pattern_list(user, arg, len, 0) != 1)
663 debug("user %.100s matched 'User %.100s' at "
664 "line %d", user, arg, line);
665 } else if (strcasecmp(attrib, "group") == 0) {
666 switch (match_cfg_line_group(arg, line, user)) {
672 } else if (strcasecmp(attrib, "host") == 0) {
677 if (match_hostname(host, arg, len) != 1)
680 debug("connection from %.100s matched 'Host "
681 "%.100s' at line %d", host, arg, line);
682 } else if (strcasecmp(attrib, "address") == 0) {
687 if (match_hostname(address, arg, len) != 1)
690 debug("connection from %.100s matched 'Address "
691 "%.100s' at line %d", address, arg, line);
693 error("Unsupported Match attribute %s", attrib);
698 debug3("match %sfound", result ? "" : "not ");
703 #define WHITESPACE " \t\r\n"
706 process_server_config_line(ServerOptions *options, char *line,
707 const char *filename, int linenum, int *activep, const char *user,
708 const char *host, const char *address)
710 char *cp, **charptr, *arg, *p;
711 int cmdline = 0, *intptr, value, n;
712 ServerOpCodes opcode;
718 if ((arg = strdelim(&cp)) == NULL)
720 /* Ignore leading whitespace */
723 if (!arg || !*arg || *arg == '#')
727 opcode = parse_token(arg, filename, linenum, &flags);
729 if (activep == NULL) { /* We are processing a command line directive */
733 if (*activep && opcode != sMatch)
734 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
735 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
737 fatal("%s line %d: Directive '%s' is not allowed "
738 "within a Match block", filename, linenum, arg);
739 } else { /* this is a directive we have already processed */
747 /* Portable-specific options */
749 intptr = &options->use_pam;
752 /* Standard Options */
756 /* ignore ports from configfile if cmdline specifies ports */
757 if (options->ports_from_cmdline)
759 if (options->listen_addrs != NULL)
760 fatal("%s line %d: ports must be specified before "
761 "ListenAddress.", filename, linenum);
762 if (options->num_ports >= MAX_PORTS)
763 fatal("%s line %d: too many ports.",
766 if (!arg || *arg == '\0')
767 fatal("%s line %d: missing port number.",
769 options->ports[options->num_ports++] = a2port(arg);
770 if (options->ports[options->num_ports-1] == 0)
771 fatal("%s line %d: Badly formatted port number.",
776 intptr = &options->server_key_bits;
779 if (!arg || *arg == '\0')
780 fatal("%s line %d: missing integer value.",
783 if (*activep && *intptr == -1)
787 case sLoginGraceTime:
788 intptr = &options->login_grace_time;
791 if (!arg || *arg == '\0')
792 fatal("%s line %d: missing time value.",
794 if ((value = convtime(arg)) == -1)
795 fatal("%s line %d: invalid time value.",
801 case sKeyRegenerationTime:
802 intptr = &options->key_regeneration_time;
807 if (arg == NULL || *arg == '\0')
808 fatal("%s line %d: missing address",
810 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
811 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
812 && strchr(p+1, ':') != NULL) {
813 add_listen_addr(options, arg, 0);
818 fatal("%s line %d: bad address:port usage",
820 p = cleanhostname(p);
823 else if ((port = a2port(arg)) == 0)
824 fatal("%s line %d: bad port number", filename, linenum);
826 add_listen_addr(options, p, port);
832 if (!arg || *arg == '\0')
833 fatal("%s line %d: missing address family.",
835 intptr = &options->address_family;
836 if (options->listen_addrs != NULL)
837 fatal("%s line %d: address family must be specified before "
838 "ListenAddress.", filename, linenum);
839 if (strcasecmp(arg, "inet") == 0)
841 else if (strcasecmp(arg, "inet6") == 0)
843 else if (strcasecmp(arg, "any") == 0)
846 fatal("%s line %d: unsupported address family \"%s\".",
847 filename, linenum, arg);
853 intptr = &options->num_host_key_files;
854 if (*intptr >= MAX_HOSTKEYS)
855 fatal("%s line %d: too many host keys specified (max %d).",
856 filename, linenum, MAX_HOSTKEYS);
857 charptr = &options->host_key_files[*intptr];
860 if (!arg || *arg == '\0')
861 fatal("%s line %d: missing file name.",
863 if (*activep && *charptr == NULL) {
864 *charptr = tilde_expand_filename(arg, getuid());
865 /* increase optional counter */
867 *intptr = *intptr + 1;
872 charptr = &options->pid_file;
875 case sPermitRootLogin:
876 intptr = &options->permit_root_login;
878 if (!arg || *arg == '\0')
879 fatal("%s line %d: missing yes/"
880 "without-password/forced-commands-only/no "
881 "argument.", filename, linenum);
882 value = 0; /* silence compiler */
883 if (strcmp(arg, "without-password") == 0)
884 value = PERMIT_NO_PASSWD;
885 else if (strcmp(arg, "forced-commands-only") == 0)
886 value = PERMIT_FORCED_ONLY;
887 else if (strcmp(arg, "yes") == 0)
889 else if (strcmp(arg, "no") == 0)
892 fatal("%s line %d: Bad yes/"
893 "without-password/forced-commands-only/no "
894 "argument: %s", filename, linenum, arg);
900 intptr = &options->ignore_rhosts;
903 if (!arg || *arg == '\0')
904 fatal("%s line %d: missing yes/no argument.",
906 value = 0; /* silence compiler */
907 if (strcmp(arg, "yes") == 0)
909 else if (strcmp(arg, "no") == 0)
912 fatal("%s line %d: Bad yes/no argument: %s",
913 filename, linenum, arg);
914 if (*activep && *intptr == -1)
919 intptr = &options->none_enabled;
923 intptr = &options->tcp_rcv_buf_poll;
927 intptr = &options->hpn_disabled;
931 intptr = &options->hpn_buffer_size;
934 case sIgnoreUserKnownHosts:
935 intptr = &options->ignore_user_known_hosts;
938 case sRhostsRSAAuthentication:
939 intptr = &options->rhosts_rsa_authentication;
942 case sHostbasedAuthentication:
943 intptr = &options->hostbased_authentication;
946 case sHostbasedUsesNameFromPacketOnly:
947 intptr = &options->hostbased_uses_name_from_packet_only;
950 case sRSAAuthentication:
951 intptr = &options->rsa_authentication;
954 case sPubkeyAuthentication:
955 intptr = &options->pubkey_authentication;
958 case sKerberosAuthentication:
959 intptr = &options->kerberos_authentication;
962 case sKerberosOrLocalPasswd:
963 intptr = &options->kerberos_or_local_passwd;
966 case sKerberosTicketCleanup:
967 intptr = &options->kerberos_ticket_cleanup;
970 case sKerberosGetAFSToken:
971 intptr = &options->kerberos_get_afs_token;
974 case sGssAuthentication:
975 intptr = &options->gss_authentication;
979 intptr = &options->gss_keyex;
982 case sGssCleanupCreds:
983 intptr = &options->gss_cleanup_creds;
986 case sGssStrictAcceptor:
987 intptr = &options->gss_strict_acceptor;
991 charptr = &options->gss_creds_path;
994 case sGsiAllowLimitedProxy:
995 intptr = &options->gsi_allow_limited_proxy;
999 case sAllowSessionHooks:
1000 intptr = &options->session_hooks_allow;
1002 case sSessionHookStartupCmd:
1003 case sSessionHookShutdownCmd:
1004 arg = strdelim(&cp);
1005 if (!arg || *arg == '\0')
1006 fatal("%s line %d: empty session hook command",
1008 if (opcode==sSessionHookStartupCmd)
1009 options->session_hooks_startup_cmd = strdup(arg);
1011 options->session_hooks_shutdown_cmd = strdup(arg);
1015 case sPasswordAuthentication:
1016 intptr = &options->password_authentication;
1019 case sKbdInteractiveAuthentication:
1020 intptr = &options->kbd_interactive_authentication;
1023 case sChallengeResponseAuthentication:
1024 intptr = &options->challenge_response_authentication;
1028 intptr = &options->print_motd;
1032 intptr = &options->print_lastlog;
1035 case sX11Forwarding:
1036 intptr = &options->x11_forwarding;
1039 case sX11DisplayOffset:
1040 intptr = &options->x11_display_offset;
1043 case sX11UseLocalhost:
1044 intptr = &options->x11_use_localhost;
1047 case sXAuthLocation:
1048 charptr = &options->xauth_location;
1049 goto parse_filename;
1052 intptr = &options->strict_modes;
1056 intptr = &options->tcp_keep_alive;
1060 intptr = &options->permit_empty_passwd;
1063 case sPermitUserEnvironment:
1064 intptr = &options->permit_user_env;
1068 intptr = &options->use_login;
1072 intptr = &options->compression;
1073 arg = strdelim(&cp);
1074 if (!arg || *arg == '\0')
1075 fatal("%s line %d: missing yes/no/delayed "
1076 "argument.", filename, linenum);
1077 value = 0; /* silence compiler */
1078 if (strcmp(arg, "delayed") == 0)
1079 value = COMP_DELAYED;
1080 else if (strcmp(arg, "yes") == 0)
1082 else if (strcmp(arg, "no") == 0)
1085 fatal("%s line %d: Bad yes/no/delayed "
1086 "argument: %s", filename, linenum, arg);
1092 intptr = &options->gateway_ports;
1093 arg = strdelim(&cp);
1094 if (!arg || *arg == '\0')
1095 fatal("%s line %d: missing yes/no/clientspecified "
1096 "argument.", filename, linenum);
1097 value = 0; /* silence compiler */
1098 if (strcmp(arg, "clientspecified") == 0)
1100 else if (strcmp(arg, "yes") == 0)
1102 else if (strcmp(arg, "no") == 0)
1105 fatal("%s line %d: Bad yes/no/clientspecified "
1106 "argument: %s", filename, linenum, arg);
1107 if (*activep && *intptr == -1)
1112 intptr = &options->use_dns;
1116 intptr = (int *) &options->log_facility;
1117 arg = strdelim(&cp);
1118 value = log_facility_number(arg);
1119 if (value == SYSLOG_FACILITY_NOT_SET)
1120 fatal("%.200s line %d: unsupported log facility '%s'",
1121 filename, linenum, arg ? arg : "<NONE>");
1123 *intptr = (SyslogFacility) value;
1127 intptr = (int *) &options->log_level;
1128 arg = strdelim(&cp);
1129 value = log_level_number(arg);
1130 if (value == SYSLOG_LEVEL_NOT_SET)
1131 fatal("%.200s line %d: unsupported log level '%s'",
1132 filename, linenum, arg ? arg : "<NONE>");
1134 *intptr = (LogLevel) value;
1137 case sAllowTcpForwarding:
1138 intptr = &options->allow_tcp_forwarding;
1141 case sUsePrivilegeSeparation:
1142 intptr = &use_privsep;
1146 while ((arg = strdelim(&cp)) && *arg != '\0') {
1147 if (options->num_allow_users >= MAX_ALLOW_USERS)
1148 fatal("%s line %d: too many allow users.",
1150 options->allow_users[options->num_allow_users++] =
1156 while ((arg = strdelim(&cp)) && *arg != '\0') {
1157 if (options->num_deny_users >= MAX_DENY_USERS)
1158 fatal("%s line %d: too many deny users.",
1160 options->deny_users[options->num_deny_users++] =
1166 while ((arg = strdelim(&cp)) && *arg != '\0') {
1167 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1168 fatal("%s line %d: too many allow groups.",
1170 options->allow_groups[options->num_allow_groups++] =
1176 while ((arg = strdelim(&cp)) && *arg != '\0') {
1177 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1178 fatal("%s line %d: too many deny groups.",
1180 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1185 arg = strdelim(&cp);
1186 if (!arg || *arg == '\0')
1187 fatal("%s line %d: Missing argument.", filename, linenum);
1188 if (!ciphers_valid(arg))
1189 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1190 filename, linenum, arg ? arg : "<NONE>");
1191 if (options->ciphers == NULL)
1192 options->ciphers = xstrdup(arg);
1196 arg = strdelim(&cp);
1197 if (!arg || *arg == '\0')
1198 fatal("%s line %d: Missing argument.", filename, linenum);
1199 if (!mac_valid(arg))
1200 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1201 filename, linenum, arg ? arg : "<NONE>");
1202 if (options->macs == NULL)
1203 options->macs = xstrdup(arg);
1207 intptr = &options->protocol;
1208 arg = strdelim(&cp);
1209 if (!arg || *arg == '\0')
1210 fatal("%s line %d: Missing argument.", filename, linenum);
1211 value = proto_spec(arg);
1212 if (value == SSH_PROTO_UNKNOWN)
1213 fatal("%s line %d: Bad protocol spec '%s'.",
1214 filename, linenum, arg ? arg : "<NONE>");
1215 if (*intptr == SSH_PROTO_UNKNOWN)
1220 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1221 fatal("%s line %d: too many subsystems defined.",
1224 arg = strdelim(&cp);
1225 if (!arg || *arg == '\0')
1226 fatal("%s line %d: Missing subsystem name.",
1229 arg = strdelim(&cp);
1232 for (i = 0; i < options->num_subsystems; i++)
1233 if (strcmp(arg, options->subsystem_name[i]) == 0)
1234 fatal("%s line %d: Subsystem '%s' already defined.",
1235 filename, linenum, arg);
1236 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1237 arg = strdelim(&cp);
1238 if (!arg || *arg == '\0')
1239 fatal("%s line %d: Missing subsystem command.",
1241 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1243 /* Collect arguments (separate to executable) */
1245 len = strlen(p) + 1;
1246 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1247 len += 1 + strlen(arg);
1248 p = xrealloc(p, 1, len);
1249 strlcat(p, " ", len);
1250 strlcat(p, arg, len);
1252 options->subsystem_args[options->num_subsystems] = p;
1253 options->num_subsystems++;
1257 arg = strdelim(&cp);
1258 if (!arg || *arg == '\0')
1259 fatal("%s line %d: Missing MaxStartups spec.",
1261 if ((n = sscanf(arg, "%d:%d:%d",
1262 &options->max_startups_begin,
1263 &options->max_startups_rate,
1264 &options->max_startups)) == 3) {
1265 if (options->max_startups_begin >
1266 options->max_startups ||
1267 options->max_startups_rate > 100 ||
1268 options->max_startups_rate < 1)
1269 fatal("%s line %d: Illegal MaxStartups spec.",
1272 fatal("%s line %d: Illegal MaxStartups spec.",
1275 options->max_startups = options->max_startups_begin;
1279 intptr = &options->max_authtries;
1283 charptr = &options->banner;
1284 goto parse_filename;
1286 * These options can contain %X options expanded at
1287 * connect time, so that you can specify paths like:
1289 * AuthorizedKeysFile /etc/ssh_keys/%u
1291 case sAuthorizedKeysFile:
1292 case sAuthorizedKeysFile2:
1293 charptr = (opcode == sAuthorizedKeysFile) ?
1294 &options->authorized_keys_file :
1295 &options->authorized_keys_file2;
1296 goto parse_filename;
1298 case sClientAliveInterval:
1299 intptr = &options->client_alive_interval;
1302 case sClientAliveCountMax:
1303 intptr = &options->client_alive_count_max;
1307 while ((arg = strdelim(&cp)) && *arg != '\0') {
1308 if (strchr(arg, '=') != NULL)
1309 fatal("%s line %d: Invalid environment name.",
1311 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1312 fatal("%s line %d: too many allow env.",
1316 options->accept_env[options->num_accept_env++] =
1322 intptr = &options->permit_tun;
1323 arg = strdelim(&cp);
1324 if (!arg || *arg == '\0')
1325 fatal("%s line %d: Missing yes/point-to-point/"
1326 "ethernet/no argument.", filename, linenum);
1327 value = 0; /* silence compiler */
1328 if (strcasecmp(arg, "ethernet") == 0)
1329 value = SSH_TUNMODE_ETHERNET;
1330 else if (strcasecmp(arg, "point-to-point") == 0)
1331 value = SSH_TUNMODE_POINTOPOINT;
1332 else if (strcasecmp(arg, "yes") == 0)
1333 value = SSH_TUNMODE_YES;
1334 else if (strcasecmp(arg, "no") == 0)
1335 value = SSH_TUNMODE_NO;
1337 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1338 "no argument: %s", filename, linenum, arg);
1345 fatal("Match directive not supported as a command-line "
1347 value = match_cfg_line(&cp, linenum, user, host, address);
1349 fatal("%s line %d: Bad Match condition", filename,
1355 arg = strdelim(&cp);
1356 if (!arg || *arg == '\0')
1357 fatal("%s line %d: missing PermitOpen specification",
1359 n = options->num_permitted_opens; /* modified later */
1360 if (strcmp(arg, "any") == 0) {
1361 if (*activep && n == -1) {
1362 channel_clear_adm_permitted_opens();
1363 options->num_permitted_opens = 0;
1367 if (*activep && n == -1)
1368 channel_clear_adm_permitted_opens();
1369 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1372 fatal("%s line %d: missing host in PermitOpen",
1374 p = cleanhostname(p);
1375 if (arg == NULL || (port = a2port(arg)) == 0)
1376 fatal("%s line %d: bad port number in "
1377 "PermitOpen", filename, linenum);
1378 if (*activep && n == -1)
1379 options->num_permitted_opens =
1380 channel_add_adm_permitted_opens(p, port);
1386 fatal("%.200s line %d: Missing argument.", filename,
1388 len = strspn(cp, WHITESPACE);
1389 if (*activep && options->adm_forced_command == NULL)
1390 options->adm_forced_command = xstrdup(cp + len);
1394 logit("%s line %d: Deprecated option %s",
1395 filename, linenum, arg);
1397 arg = strdelim(&cp);
1401 logit("%s line %d: Unsupported option %s",
1402 filename, linenum, arg);
1404 arg = strdelim(&cp);
1408 fatal("%s line %d: Missing handler for opcode %s (%d)",
1409 filename, linenum, arg, opcode);
1411 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1412 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1413 filename, linenum, arg);
1417 /* Reads the server configuration file. */
1420 load_server_config(const char *filename, Buffer *conf)
1422 char line[1024], *cp;
1425 debug2("%s: filename %s", __func__, filename);
1426 if ((f = fopen(filename, "r")) == NULL) {
1431 while (fgets(line, sizeof(line), f)) {
1433 * Trim out comments and strip whitespace
1434 * NB - preserve newlines, they are needed to reproduce
1435 * line numbers later for error messages
1437 if ((cp = strchr(line, '#')) != NULL)
1438 memcpy(cp, "\n", 2);
1439 cp = line + strspn(line, " \t\r");
1441 buffer_append(conf, cp, strlen(cp));
1443 buffer_append(conf, "\0", 1);
1445 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1449 parse_server_match_config(ServerOptions *options, const char *user,
1450 const char *host, const char *address)
1454 initialize_server_options(&mo);
1455 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1456 copy_set_server_options(options, &mo, 0);
1460 #define M_CP_INTOPT(n) do {\
1464 #define M_CP_STROPT(n) do {\
1465 if (src->n != NULL) { \
1466 if (dst->n != NULL) \
1473 * Copy any supported values that are set.
1475 * If the preauth flag is set, we do not bother copying the the string or
1476 * array values that are not used pre-authentication, because any that we
1477 * do use must be explictly sent in mm_getpwnamallow().
1480 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1482 M_CP_INTOPT(password_authentication);
1483 M_CP_INTOPT(gss_authentication);
1484 M_CP_INTOPT(rsa_authentication);
1485 M_CP_INTOPT(pubkey_authentication);
1486 M_CP_INTOPT(kerberos_authentication);
1487 M_CP_INTOPT(hostbased_authentication);
1488 M_CP_INTOPT(kbd_interactive_authentication);
1490 M_CP_INTOPT(allow_tcp_forwarding);
1491 M_CP_INTOPT(gateway_ports);
1492 M_CP_INTOPT(x11_display_offset);
1493 M_CP_INTOPT(x11_forwarding);
1494 M_CP_INTOPT(x11_use_localhost);
1496 M_CP_STROPT(banner);
1499 M_CP_STROPT(adm_forced_command);
1506 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1507 const char *user, const char *host, const char *address)
1509 int active, linenum, bad_options = 0;
1510 char *cp, *obuf, *cbuf;
1512 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1514 obuf = cbuf = xstrdup(buffer_ptr(conf));
1515 active = user ? 0 : 1;
1517 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1518 if (process_server_config_line(options, cp, filename,
1519 linenum++, &active, user, host, address) != 0)
1523 if (bad_options > 0)
1524 fatal("%s: terminating, %d bad configuration options",
1525 filename, bad_options);