1 /* $OpenBSD: servconf.c,v 1.165 2006/08/14 12:40:25 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)
143 /* Portable-specific options */
144 if (options->use_pam == -1)
145 options->use_pam = 0;
147 /* Standard Options */
148 if (options->protocol == SSH_PROTO_UNKNOWN)
149 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
150 if (options->num_host_key_files == 0) {
151 /* fill default hostkeys for protocols */
152 if (options->protocol & SSH_PROTO_1)
153 options->host_key_files[options->num_host_key_files++] =
155 if (options->protocol & SSH_PROTO_2) {
156 options->host_key_files[options->num_host_key_files++] =
157 _PATH_HOST_RSA_KEY_FILE;
158 options->host_key_files[options->num_host_key_files++] =
159 _PATH_HOST_DSA_KEY_FILE;
162 if (options->num_ports == 0)
163 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
164 if (options->listen_addrs == NULL)
165 add_listen_addr(options, NULL, 0);
166 if (options->pid_file == NULL)
167 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
168 if (options->server_key_bits == -1)
169 options->server_key_bits = 768;
170 if (options->login_grace_time == -1)
171 options->login_grace_time = 120;
172 if (options->key_regeneration_time == -1)
173 options->key_regeneration_time = 3600;
174 if (options->permit_root_login == PERMIT_NOT_SET)
175 options->permit_root_login = PERMIT_YES;
176 if (options->ignore_rhosts == -1)
177 options->ignore_rhosts = 1;
178 if (options->ignore_user_known_hosts == -1)
179 options->ignore_user_known_hosts = 0;
180 if (options->print_motd == -1)
181 options->print_motd = 1;
182 if (options->print_lastlog == -1)
183 options->print_lastlog = 1;
184 if (options->x11_forwarding == -1)
185 options->x11_forwarding = 0;
186 if (options->x11_display_offset == -1)
187 options->x11_display_offset = 10;
188 if (options->x11_use_localhost == -1)
189 options->x11_use_localhost = 1;
190 if (options->xauth_location == NULL)
191 options->xauth_location = _PATH_XAUTH;
192 if (options->strict_modes == -1)
193 options->strict_modes = 1;
194 if (options->tcp_keep_alive == -1)
195 options->tcp_keep_alive = 1;
196 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
197 options->log_facility = SYSLOG_FACILITY_AUTH;
198 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
199 options->log_level = SYSLOG_LEVEL_INFO;
200 if (options->rhosts_rsa_authentication == -1)
201 options->rhosts_rsa_authentication = 0;
202 if (options->hostbased_authentication == -1)
203 options->hostbased_authentication = 0;
204 if (options->hostbased_uses_name_from_packet_only == -1)
205 options->hostbased_uses_name_from_packet_only = 0;
206 if (options->rsa_authentication == -1)
207 options->rsa_authentication = 1;
208 if (options->pubkey_authentication == -1)
209 options->pubkey_authentication = 1;
210 if (options->kerberos_authentication == -1)
211 options->kerberos_authentication = 0;
212 if (options->kerberos_or_local_passwd == -1)
213 options->kerberos_or_local_passwd = 1;
214 if (options->kerberos_ticket_cleanup == -1)
215 options->kerberos_ticket_cleanup = 1;
216 if (options->kerberos_get_afs_token == -1)
217 options->kerberos_get_afs_token = 0;
218 if (options->gss_authentication == -1)
219 options->gss_authentication = 1;
220 if (options->gss_keyex == -1)
221 options->gss_keyex = 1;
222 if (options->gss_cleanup_creds == -1)
223 options->gss_cleanup_creds = 1;
224 if (options->gss_strict_acceptor == -1)
225 options->gss_strict_acceptor = 0;
226 if (options->gsi_allow_limited_proxy == -1)
227 options->gsi_allow_limited_proxy = 0;
228 if (options->password_authentication == -1)
229 options->password_authentication = 1;
230 if (options->kbd_interactive_authentication == -1)
231 options->kbd_interactive_authentication = 0;
232 if (options->challenge_response_authentication == -1)
233 options->challenge_response_authentication = 1;
234 if (options->permit_empty_passwd == -1)
235 options->permit_empty_passwd = 0;
236 if (options->permit_user_env == -1)
237 options->permit_user_env = 0;
238 if (options->use_login == -1)
239 options->use_login = 0;
240 if (options->compression == -1)
241 options->compression = COMP_DELAYED;
242 if (options->allow_tcp_forwarding == -1)
243 options->allow_tcp_forwarding = 1;
244 if (options->gateway_ports == -1)
245 options->gateway_ports = 0;
246 if (options->max_startups == -1)
247 options->max_startups = 10;
248 if (options->max_startups_rate == -1)
249 options->max_startups_rate = 100; /* 100% */
250 if (options->max_startups_begin == -1)
251 options->max_startups_begin = options->max_startups;
252 if (options->max_authtries == -1)
253 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
254 if (options->use_dns == -1)
255 options->use_dns = 1;
256 if (options->client_alive_interval == -1)
257 options->client_alive_interval = 0;
258 if (options->client_alive_count_max == -1)
259 options->client_alive_count_max = 3;
260 if (options->authorized_keys_file2 == NULL) {
261 /* authorized_keys_file2 falls back to authorized_keys_file */
262 if (options->authorized_keys_file != NULL)
263 options->authorized_keys_file2 = options->authorized_keys_file;
265 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
267 if (options->authorized_keys_file == NULL)
268 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
269 if (options->permit_tun == -1)
270 options->permit_tun = SSH_TUNMODE_NO;
272 if (options->hpn_disabled == -1)
273 options->hpn_disabled = 0;
275 if (options->hpn_buffer_size == -1)
276 options->hpn_buffer_size = 2*1024*1024;
278 if (options->hpn_buffer_size == 0)
279 options->hpn_buffer_size = 1;
280 /* limit the maximum buffer to 7MB */
281 if (options->hpn_buffer_size > 7168)
282 options->hpn_buffer_size = 7168;
283 options->hpn_buffer_size *=1024;
286 /* Turn privilege separation on by default */
287 if (use_privsep == -1)
293 if (use_privsep && options->compression == 1) {
294 error("This platform does not support both privilege "
295 "separation and compression");
296 error("Compression disabled");
297 options->compression = 0;
303 /* Keyword tokens. */
305 sBadOption, /* == unknown option */
306 /* Portable-specific options */
308 /* Standard Options */
309 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
310 sPermitRootLogin, sLogFacility, sLogLevel,
311 sRhostsRSAAuthentication, sRSAAuthentication,
312 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
313 sKerberosGetAFSToken,
314 sKerberosTgtPassing, sChallengeResponseAuthentication,
316 sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
318 sPasswordAuthentication, sKbdInteractiveAuthentication,
319 sListenAddress, sAddressFamily,
320 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
321 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
322 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
323 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
324 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
325 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
326 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
327 sMaxStartups, sMaxAuthTries,
328 sBanner, sUseDNS, sHostbasedAuthentication,
329 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
330 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
331 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
333 sGsiAllowLimitedProxy,
334 sAcceptEnv, sPermitTunnel,
335 sMatch, sPermitOpen, sForceCommand,
336 sUsePrivilegeSeparation,
337 sNoneEnabled, sTcpRcvBufPoll,
338 sHPNDisabled, sHPNBufferSize,
339 sDeprecated, sUnsupported
342 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
343 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
344 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
346 /* Textual representation of the tokens. */
349 ServerOpCodes opcode;
352 /* Portable-specific options */
354 { "usepam", sUsePAM, SSHCFG_GLOBAL },
356 { "usepam", sUnsupported, SSHCFG_GLOBAL },
358 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
359 /* Standard Options */
360 { "port", sPort, SSHCFG_GLOBAL },
361 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
362 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
363 { "pidfile", sPidFile, SSHCFG_GLOBAL },
364 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
365 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
366 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
367 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
368 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
369 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
370 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
371 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
372 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
373 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
374 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
375 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
376 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
378 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
379 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
380 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
382 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
384 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
387 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
388 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
389 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
390 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
392 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
393 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
395 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
396 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
397 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
398 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
400 { "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL },
403 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
404 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
405 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
406 { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
408 { "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL },
412 { "allowsessionhooks", sAllowSessionHooks, SSHCFG_GLOBAL },
413 { "sessionhookstartupcmd", sSessionHookStartupCmd, SSHCFG_GLOBAL },
414 { "sessionhookshutdowncmd", sSessionHookShutdownCmd, SSHCFG_GLOBAL },
416 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
417 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
418 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
419 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
420 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
421 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
422 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
423 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
424 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
425 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
426 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
427 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
428 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
429 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
430 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
431 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
432 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
433 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
434 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
435 { "compression", sCompression, SSHCFG_GLOBAL },
436 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
437 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
438 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
439 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
440 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
441 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
442 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
443 { "ciphers", sCiphers, SSHCFG_GLOBAL },
444 { "macs", sMacs, SSHCFG_GLOBAL },
445 { "protocol", sProtocol, SSHCFG_GLOBAL },
446 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
447 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
448 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
449 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
450 { "banner", sBanner, SSHCFG_GLOBAL },
451 { "usedns", sUseDNS, SSHCFG_GLOBAL },
452 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
453 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
454 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
455 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
456 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
457 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
458 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
459 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
460 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
461 { "match", sMatch, SSHCFG_ALL },
462 { "permitopen", sPermitOpen, SSHCFG_ALL },
463 { "forcecommand", sForceCommand, SSHCFG_ALL },
464 { "noneenabled", sNoneEnabled },
465 { "hpndisabled", sHPNDisabled },
466 { "hpnbuffersize", sHPNBufferSize },
467 { "tcprcvbufpoll", sTcpRcvBufPoll },
468 { NULL, sBadOption, 0 }
472 * Returns the number of the token pointed to by cp or sBadOption.
476 parse_token(const char *cp, const char *filename,
477 int linenum, u_int *flags)
481 for (i = 0; keywords[i].name; i++)
482 if (strcasecmp(cp, keywords[i].name) == 0) {
483 *flags = keywords[i].flags;
484 return keywords[i].opcode;
487 error("%s: line %d: Bad configuration option: %s",
488 filename, linenum, cp);
493 add_listen_addr(ServerOptions *options, char *addr, u_short port)
497 if (options->num_ports == 0)
498 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
499 if (options->address_family == -1)
500 options->address_family = AF_UNSPEC;
502 for (i = 0; i < options->num_ports; i++)
503 add_one_listen_addr(options, addr, options->ports[i]);
505 add_one_listen_addr(options, addr, port);
509 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
511 struct addrinfo hints, *ai, *aitop;
512 char strport[NI_MAXSERV];
515 memset(&hints, 0, sizeof(hints));
516 hints.ai_family = options->address_family;
517 hints.ai_socktype = SOCK_STREAM;
518 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
519 snprintf(strport, sizeof strport, "%u", port);
520 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
521 fatal("bad addr or host: %s (%s)",
522 addr ? addr : "<NULL>",
523 gai_strerror(gaierr));
524 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
526 ai->ai_next = options->listen_addrs;
527 options->listen_addrs = aitop;
531 * The strategy for the Match blocks is that the config file is parsed twice.
533 * The first time is at startup. activep is initialized to 1 and the
534 * directives in the global context are processed and acted on. Hitting a
535 * Match directive unsets activep and the directives inside the block are
536 * checked for syntax only.
538 * The second time is after a connection has been established but before
539 * authentication. activep is initialized to 2 and global config directives
540 * are ignored since they have already been processed. If the criteria in a
541 * Match block is met, activep is set and the subsequent directives
542 * processed and actioned until EOF or another Match block unsets it. Any
543 * options set are copied into the main server config.
545 * Potential additions/improvements:
546 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
548 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
549 * Match Address 192.168.0.*
554 * AllowTcpForwarding yes
555 * GatewayPorts clientspecified
558 * - Add a PermittedChannelRequests directive
560 * PermittedChannelRequests session,forwarded-tcpip
564 match_cfg_line_group(const char *grps, int line, const char *user)
568 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
572 * Even if we do not have a user yet, we still need to check for
575 arg = cp = xstrdup(grps);
576 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
577 if (ngrps >= MAX_MATCH_GROUPS) {
578 error("line %d: too many groups in Match Group", line);
582 grplist[ngrps++] = p;
588 if ((pw = getpwnam(user)) == NULL) {
589 debug("Can't match group at line %d because user %.100s does "
590 "not exist", line, user);
591 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
592 debug("Can't Match group because user %.100s not in any group "
593 "at line %d", user, line);
594 } else if (ga_match(grplist, ngrps) != 1) {
595 debug("user %.100s does not match group %.100s at line %d",
598 debug("user %.100s matched group %.100s at line %d", user,
609 match_cfg_line(char **condition, int line, const char *user, const char *host,
613 char *arg, *attrib, *cp = *condition;
617 debug3("checking syntax for 'Match %s'", cp);
619 debug3("checking match for '%s' user %s host %s addr %s", cp,
620 user ? user : "(null)", host ? host : "(null)",
621 address ? address : "(null)");
623 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
624 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
625 error("Missing Match criteria for %s", attrib);
629 if (strcasecmp(attrib, "user") == 0) {
634 if (match_pattern_list(user, arg, len, 0) != 1)
637 debug("user %.100s matched 'User %.100s' at "
638 "line %d", user, arg, line);
639 } else if (strcasecmp(attrib, "group") == 0) {
640 switch (match_cfg_line_group(arg, line, user)) {
646 } else if (strcasecmp(attrib, "host") == 0) {
651 if (match_hostname(host, arg, len) != 1)
654 debug("connection from %.100s matched 'Host "
655 "%.100s' at line %d", host, arg, line);
656 } else if (strcasecmp(attrib, "address") == 0) {
657 debug("address '%s' arg '%s'", address, arg);
662 if (match_hostname(address, arg, len) != 1)
665 debug("connection from %.100s matched 'Address "
666 "%.100s' at line %d", address, arg, line);
668 error("Unsupported Match attribute %s", attrib);
673 debug3("match %sfound", result ? "" : "not ");
678 #define WHITESPACE " \t\r\n"
681 process_server_config_line(ServerOptions *options, char *line,
682 const char *filename, int linenum, int *activep, const char *user,
683 const char *host, const char *address)
685 char *cp, **charptr, *arg, *p;
686 int cmdline = 0, *intptr, value, n;
687 ServerOpCodes opcode;
693 if ((arg = strdelim(&cp)) == NULL)
695 /* Ignore leading whitespace */
698 if (!arg || !*arg || *arg == '#')
702 opcode = parse_token(arg, filename, linenum, &flags);
704 if (activep == NULL) { /* We are processing a command line directive */
708 if (*activep && opcode != sMatch)
709 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
710 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
712 fatal("%s line %d: Directive '%s' is not allowed "
713 "within a Match block", filename, linenum, arg);
714 } else { /* this is a directive we have already processed */
722 /* Portable-specific options */
724 intptr = &options->use_pam;
727 /* Standard Options */
731 /* ignore ports from configfile if cmdline specifies ports */
732 if (options->ports_from_cmdline)
734 if (options->listen_addrs != NULL)
735 fatal("%s line %d: ports must be specified before "
736 "ListenAddress.", filename, linenum);
737 if (options->num_ports >= MAX_PORTS)
738 fatal("%s line %d: too many ports.",
741 if (!arg || *arg == '\0')
742 fatal("%s line %d: missing port number.",
744 options->ports[options->num_ports++] = a2port(arg);
745 if (options->ports[options->num_ports-1] == 0)
746 fatal("%s line %d: Badly formatted port number.",
751 intptr = &options->server_key_bits;
754 if (!arg || *arg == '\0')
755 fatal("%s line %d: missing integer value.",
758 if (*activep && *intptr == -1)
762 case sLoginGraceTime:
763 intptr = &options->login_grace_time;
766 if (!arg || *arg == '\0')
767 fatal("%s line %d: missing time value.",
769 if ((value = convtime(arg)) == -1)
770 fatal("%s line %d: invalid time value.",
776 case sKeyRegenerationTime:
777 intptr = &options->key_regeneration_time;
782 if (arg == NULL || *arg == '\0')
783 fatal("%s line %d: missing address",
785 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
786 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
787 && strchr(p+1, ':') != NULL) {
788 add_listen_addr(options, arg, 0);
793 fatal("%s line %d: bad address:port usage",
795 p = cleanhostname(p);
798 else if ((port = a2port(arg)) == 0)
799 fatal("%s line %d: bad port number", filename, linenum);
801 add_listen_addr(options, p, port);
807 if (!arg || *arg == '\0')
808 fatal("%s line %d: missing address family.",
810 intptr = &options->address_family;
811 if (options->listen_addrs != NULL)
812 fatal("%s line %d: address family must be specified before "
813 "ListenAddress.", filename, linenum);
814 if (strcasecmp(arg, "inet") == 0)
816 else if (strcasecmp(arg, "inet6") == 0)
818 else if (strcasecmp(arg, "any") == 0)
821 fatal("%s line %d: unsupported address family \"%s\".",
822 filename, linenum, arg);
828 intptr = &options->num_host_key_files;
829 if (*intptr >= MAX_HOSTKEYS)
830 fatal("%s line %d: too many host keys specified (max %d).",
831 filename, linenum, MAX_HOSTKEYS);
832 charptr = &options->host_key_files[*intptr];
835 if (!arg || *arg == '\0')
836 fatal("%s line %d: missing file name.",
838 if (*activep && *charptr == NULL) {
839 *charptr = tilde_expand_filename(arg, getuid());
840 /* increase optional counter */
842 *intptr = *intptr + 1;
847 charptr = &options->pid_file;
850 case sPermitRootLogin:
851 intptr = &options->permit_root_login;
853 if (!arg || *arg == '\0')
854 fatal("%s line %d: missing yes/"
855 "without-password/forced-commands-only/no "
856 "argument.", filename, linenum);
857 value = 0; /* silence compiler */
858 if (strcmp(arg, "without-password") == 0)
859 value = PERMIT_NO_PASSWD;
860 else if (strcmp(arg, "forced-commands-only") == 0)
861 value = PERMIT_FORCED_ONLY;
862 else if (strcmp(arg, "yes") == 0)
864 else if (strcmp(arg, "no") == 0)
867 fatal("%s line %d: Bad yes/"
868 "without-password/forced-commands-only/no "
869 "argument: %s", filename, linenum, arg);
875 intptr = &options->ignore_rhosts;
878 if (!arg || *arg == '\0')
879 fatal("%s line %d: missing yes/no argument.",
881 value = 0; /* silence compiler */
882 if (strcmp(arg, "yes") == 0)
884 else if (strcmp(arg, "no") == 0)
887 fatal("%s line %d: Bad yes/no argument: %s",
888 filename, linenum, arg);
889 if (*activep && *intptr == -1)
894 intptr = &options->none_enabled;
898 intptr = &options->tcp_rcv_buf_poll;
902 intptr = &options->hpn_disabled;
906 intptr = &options->hpn_buffer_size;
909 case sIgnoreUserKnownHosts:
910 intptr = &options->ignore_user_known_hosts;
913 case sRhostsRSAAuthentication:
914 intptr = &options->rhosts_rsa_authentication;
917 case sHostbasedAuthentication:
918 intptr = &options->hostbased_authentication;
921 case sHostbasedUsesNameFromPacketOnly:
922 intptr = &options->hostbased_uses_name_from_packet_only;
925 case sRSAAuthentication:
926 intptr = &options->rsa_authentication;
929 case sPubkeyAuthentication:
930 intptr = &options->pubkey_authentication;
933 case sKerberosAuthentication:
934 intptr = &options->kerberos_authentication;
937 case sKerberosOrLocalPasswd:
938 intptr = &options->kerberos_or_local_passwd;
941 case sKerberosTicketCleanup:
942 intptr = &options->kerberos_ticket_cleanup;
945 case sKerberosGetAFSToken:
946 intptr = &options->kerberos_get_afs_token;
949 case sGssAuthentication:
950 intptr = &options->gss_authentication;
954 intptr = &options->gss_keyex;
957 case sGssCleanupCreds:
958 intptr = &options->gss_cleanup_creds;
961 case sGssStrictAcceptor:
962 intptr = &options->gss_strict_acceptor;
964 case sGsiAllowLimitedProxy:
965 intptr = &options->gsi_allow_limited_proxy;
969 case sAllowSessionHooks:
970 intptr = &options->session_hooks_allow;
972 case sSessionHookStartupCmd:
973 case sSessionHookShutdownCmd:
975 if (!arg || *arg == '\0')
976 fatal("%s line %d: empty session hook command",
978 if (opcode==sSessionHookStartupCmd)
979 options->session_hooks_startup_cmd = strdup(arg);
981 options->session_hooks_shutdown_cmd = strdup(arg);
985 case sPasswordAuthentication:
986 intptr = &options->password_authentication;
989 case sKbdInteractiveAuthentication:
990 intptr = &options->kbd_interactive_authentication;
993 case sChallengeResponseAuthentication:
994 intptr = &options->challenge_response_authentication;
998 intptr = &options->print_motd;
1002 intptr = &options->print_lastlog;
1005 case sX11Forwarding:
1006 intptr = &options->x11_forwarding;
1009 case sX11DisplayOffset:
1010 intptr = &options->x11_display_offset;
1013 case sX11UseLocalhost:
1014 intptr = &options->x11_use_localhost;
1017 case sXAuthLocation:
1018 charptr = &options->xauth_location;
1019 goto parse_filename;
1022 intptr = &options->strict_modes;
1026 intptr = &options->tcp_keep_alive;
1030 intptr = &options->permit_empty_passwd;
1033 case sPermitUserEnvironment:
1034 intptr = &options->permit_user_env;
1038 intptr = &options->use_login;
1042 intptr = &options->compression;
1043 arg = strdelim(&cp);
1044 if (!arg || *arg == '\0')
1045 fatal("%s line %d: missing yes/no/delayed "
1046 "argument.", filename, linenum);
1047 value = 0; /* silence compiler */
1048 if (strcmp(arg, "delayed") == 0)
1049 value = COMP_DELAYED;
1050 else if (strcmp(arg, "yes") == 0)
1052 else if (strcmp(arg, "no") == 0)
1055 fatal("%s line %d: Bad yes/no/delayed "
1056 "argument: %s", filename, linenum, arg);
1062 intptr = &options->gateway_ports;
1063 arg = strdelim(&cp);
1064 if (!arg || *arg == '\0')
1065 fatal("%s line %d: missing yes/no/clientspecified "
1066 "argument.", filename, linenum);
1067 value = 0; /* silence compiler */
1068 if (strcmp(arg, "clientspecified") == 0)
1070 else if (strcmp(arg, "yes") == 0)
1072 else if (strcmp(arg, "no") == 0)
1075 fatal("%s line %d: Bad yes/no/clientspecified "
1076 "argument: %s", filename, linenum, arg);
1082 intptr = &options->use_dns;
1086 intptr = (int *) &options->log_facility;
1087 arg = strdelim(&cp);
1088 value = log_facility_number(arg);
1089 if (value == SYSLOG_FACILITY_NOT_SET)
1090 fatal("%.200s line %d: unsupported log facility '%s'",
1091 filename, linenum, arg ? arg : "<NONE>");
1093 *intptr = (SyslogFacility) value;
1097 intptr = (int *) &options->log_level;
1098 arg = strdelim(&cp);
1099 value = log_level_number(arg);
1100 if (value == SYSLOG_LEVEL_NOT_SET)
1101 fatal("%.200s line %d: unsupported log level '%s'",
1102 filename, linenum, arg ? arg : "<NONE>");
1104 *intptr = (LogLevel) value;
1107 case sAllowTcpForwarding:
1108 intptr = &options->allow_tcp_forwarding;
1111 case sUsePrivilegeSeparation:
1112 intptr = &use_privsep;
1116 while ((arg = strdelim(&cp)) && *arg != '\0') {
1117 if (options->num_allow_users >= MAX_ALLOW_USERS)
1118 fatal("%s line %d: too many allow users.",
1120 options->allow_users[options->num_allow_users++] =
1126 while ((arg = strdelim(&cp)) && *arg != '\0') {
1127 if (options->num_deny_users >= MAX_DENY_USERS)
1128 fatal("%s line %d: too many deny users.",
1130 options->deny_users[options->num_deny_users++] =
1136 while ((arg = strdelim(&cp)) && *arg != '\0') {
1137 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1138 fatal("%s line %d: too many allow groups.",
1140 options->allow_groups[options->num_allow_groups++] =
1146 while ((arg = strdelim(&cp)) && *arg != '\0') {
1147 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1148 fatal("%s line %d: too many deny groups.",
1150 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1155 arg = strdelim(&cp);
1156 if (!arg || *arg == '\0')
1157 fatal("%s line %d: Missing argument.", filename, linenum);
1158 if (!ciphers_valid(arg))
1159 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1160 filename, linenum, arg ? arg : "<NONE>");
1161 if (options->ciphers == NULL)
1162 options->ciphers = xstrdup(arg);
1166 arg = strdelim(&cp);
1167 if (!arg || *arg == '\0')
1168 fatal("%s line %d: Missing argument.", filename, linenum);
1169 if (!mac_valid(arg))
1170 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1171 filename, linenum, arg ? arg : "<NONE>");
1172 if (options->macs == NULL)
1173 options->macs = xstrdup(arg);
1177 intptr = &options->protocol;
1178 arg = strdelim(&cp);
1179 if (!arg || *arg == '\0')
1180 fatal("%s line %d: Missing argument.", filename, linenum);
1181 value = proto_spec(arg);
1182 if (value == SSH_PROTO_UNKNOWN)
1183 fatal("%s line %d: Bad protocol spec '%s'.",
1184 filename, linenum, arg ? arg : "<NONE>");
1185 if (*intptr == SSH_PROTO_UNKNOWN)
1190 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1191 fatal("%s line %d: too many subsystems defined.",
1194 arg = strdelim(&cp);
1195 if (!arg || *arg == '\0')
1196 fatal("%s line %d: Missing subsystem name.",
1199 arg = strdelim(&cp);
1202 for (i = 0; i < options->num_subsystems; i++)
1203 if (strcmp(arg, options->subsystem_name[i]) == 0)
1204 fatal("%s line %d: Subsystem '%s' already defined.",
1205 filename, linenum, arg);
1206 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1207 arg = strdelim(&cp);
1208 if (!arg || *arg == '\0')
1209 fatal("%s line %d: Missing subsystem command.",
1211 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1213 /* Collect arguments (separate to executable) */
1215 len = strlen(p) + 1;
1216 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1217 len += 1 + strlen(arg);
1218 p = xrealloc(p, 1, len);
1219 strlcat(p, " ", len);
1220 strlcat(p, arg, len);
1222 options->subsystem_args[options->num_subsystems] = p;
1223 options->num_subsystems++;
1227 arg = strdelim(&cp);
1228 if (!arg || *arg == '\0')
1229 fatal("%s line %d: Missing MaxStartups spec.",
1231 if ((n = sscanf(arg, "%d:%d:%d",
1232 &options->max_startups_begin,
1233 &options->max_startups_rate,
1234 &options->max_startups)) == 3) {
1235 if (options->max_startups_begin >
1236 options->max_startups ||
1237 options->max_startups_rate > 100 ||
1238 options->max_startups_rate < 1)
1239 fatal("%s line %d: Illegal MaxStartups spec.",
1242 fatal("%s line %d: Illegal MaxStartups spec.",
1245 options->max_startups = options->max_startups_begin;
1249 intptr = &options->max_authtries;
1253 charptr = &options->banner;
1254 goto parse_filename;
1256 * These options can contain %X options expanded at
1257 * connect time, so that you can specify paths like:
1259 * AuthorizedKeysFile /etc/ssh_keys/%u
1261 case sAuthorizedKeysFile:
1262 case sAuthorizedKeysFile2:
1263 charptr = (opcode == sAuthorizedKeysFile) ?
1264 &options->authorized_keys_file :
1265 &options->authorized_keys_file2;
1266 goto parse_filename;
1268 case sClientAliveInterval:
1269 intptr = &options->client_alive_interval;
1272 case sClientAliveCountMax:
1273 intptr = &options->client_alive_count_max;
1277 while ((arg = strdelim(&cp)) && *arg != '\0') {
1278 if (strchr(arg, '=') != NULL)
1279 fatal("%s line %d: Invalid environment name.",
1281 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1282 fatal("%s line %d: too many allow env.",
1286 options->accept_env[options->num_accept_env++] =
1292 intptr = &options->permit_tun;
1293 arg = strdelim(&cp);
1294 if (!arg || *arg == '\0')
1295 fatal("%s line %d: Missing yes/point-to-point/"
1296 "ethernet/no argument.", filename, linenum);
1297 value = 0; /* silence compiler */
1298 if (strcasecmp(arg, "ethernet") == 0)
1299 value = SSH_TUNMODE_ETHERNET;
1300 else if (strcasecmp(arg, "point-to-point") == 0)
1301 value = SSH_TUNMODE_POINTOPOINT;
1302 else if (strcasecmp(arg, "yes") == 0)
1303 value = SSH_TUNMODE_YES;
1304 else if (strcasecmp(arg, "no") == 0)
1305 value = SSH_TUNMODE_NO;
1307 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1308 "no argument: %s", filename, linenum, arg);
1315 fatal("Match directive not supported as a command-line "
1317 value = match_cfg_line(&cp, linenum, user, host, address);
1319 fatal("%s line %d: Bad Match condition", filename,
1325 arg = strdelim(&cp);
1326 if (!arg || *arg == '\0')
1327 fatal("%s line %d: missing PermitOpen specification",
1329 if (strcmp(arg, "any") == 0) {
1331 channel_clear_adm_permitted_opens();
1332 options->num_permitted_opens = 0;
1336 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1339 fatal("%s line %d: missing host in PermitOpen",
1341 p = cleanhostname(p);
1342 if (arg == NULL || (port = a2port(arg)) == 0)
1343 fatal("%s line %d: bad port number in "
1344 "PermitOpen", filename, linenum);
1345 if (*activep && options->num_permitted_opens == -1) {
1346 channel_clear_adm_permitted_opens();
1347 options->num_permitted_opens =
1348 channel_add_adm_permitted_opens(p, port);
1355 fatal("%.200s line %d: Missing argument.", filename,
1357 len = strspn(cp, WHITESPACE);
1358 if (*activep && options->adm_forced_command == NULL)
1359 options->adm_forced_command = xstrdup(cp + len);
1363 logit("%s line %d: Deprecated option %s",
1364 filename, linenum, arg);
1366 arg = strdelim(&cp);
1370 logit("%s line %d: Unsupported option %s",
1371 filename, linenum, arg);
1373 arg = strdelim(&cp);
1377 fatal("%s line %d: Missing handler for opcode %s (%d)",
1378 filename, linenum, arg, opcode);
1380 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1381 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1382 filename, linenum, arg);
1386 /* Reads the server configuration file. */
1389 load_server_config(const char *filename, Buffer *conf)
1391 char line[1024], *cp;
1394 debug2("%s: filename %s", __func__, filename);
1395 if ((f = fopen(filename, "r")) == NULL) {
1400 while (fgets(line, sizeof(line), f)) {
1402 * Trim out comments and strip whitespace
1403 * NB - preserve newlines, they are needed to reproduce
1404 * line numbers later for error messages
1406 if ((cp = strchr(line, '#')) != NULL)
1407 memcpy(cp, "\n", 2);
1408 cp = line + strspn(line, " \t\r");
1410 buffer_append(conf, cp, strlen(cp));
1412 buffer_append(conf, "\0", 1);
1414 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1418 parse_server_match_config(ServerOptions *options, const char *user,
1419 const char *host, const char *address)
1423 initialize_server_options(&mo);
1424 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1425 copy_set_server_options(options, &mo);
1428 /* Copy any (supported) values that are set */
1430 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1432 if (src->allow_tcp_forwarding != -1)
1433 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1434 if (src->gateway_ports != -1)
1435 dst->gateway_ports = src->gateway_ports;
1436 if (src->adm_forced_command != NULL) {
1437 if (dst->adm_forced_command != NULL)
1438 xfree(dst->adm_forced_command);
1439 dst->adm_forced_command = src->adm_forced_command;
1441 if (src->x11_display_offset != -1)
1442 dst->x11_display_offset = src->x11_display_offset;
1443 if (src->x11_forwarding != -1)
1444 dst->x11_forwarding = src->x11_forwarding;
1445 if (src->x11_use_localhost != -1)
1446 dst->x11_use_localhost = src->x11_use_localhost;
1450 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1451 const char *user, const char *host, const char *address)
1453 int active, linenum, bad_options = 0;
1454 char *cp, *obuf, *cbuf;
1456 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1458 obuf = cbuf = xstrdup(buffer_ptr(conf));
1459 active = user ? 0 : 1;
1461 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1462 if (process_server_config_line(options, cp, filename,
1463 linenum++, &active, user, host, address) != 0)
1467 if (bad_options > 0)
1468 fatal("%s: terminating, %d bad configuration options",
1469 filename, bad_options);