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;
91 options->kerberos_get_afs_token = -1;
92 options->gss_authentication=-1;
93 options->gss_keyex = -1;
94 options->gss_cleanup_creds = -1;
95 options->gss_strict_acceptor = -1;
96 options->password_authentication = -1;
97 options->kbd_interactive_authentication = -1;
98 options->challenge_response_authentication = -1;
99 options->permit_empty_passwd = -1;
100 options->permit_user_env = -1;
101 options->use_login = -1;
102 options->compression = -1;
103 options->allow_tcp_forwarding = -1;
104 options->num_allow_users = 0;
105 options->num_deny_users = 0;
106 options->num_allow_groups = 0;
107 options->num_deny_groups = 0;
108 options->ciphers = NULL;
109 options->macs = NULL;
110 options->protocol = SSH_PROTO_UNKNOWN;
111 options->gateway_ports = -1;
112 options->num_subsystems = 0;
113 options->max_startups_begin = -1;
114 options->max_startups_rate = -1;
115 options->max_startups = -1;
116 options->max_authtries = -1;
117 options->banner = NULL;
118 options->use_dns = -1;
119 options->client_alive_interval = -1;
120 options->client_alive_count_max = -1;
121 options->authorized_keys_file = NULL;
122 options->authorized_keys_file2 = NULL;
123 options->num_accept_env = 0;
124 options->permit_tun = -1;
125 options->num_permitted_opens = -1;
126 options->adm_forced_command = NULL;
127 options->none_enabled = -1;
128 options->tcp_rcv_buf_poll = -1;
129 options->hpn_disabled = -1;
130 options->hpn_buffer_size = -1;
134 fill_default_server_options(ServerOptions *options)
138 int socksizelen = sizeof(int);
140 /* Portable-specific options */
141 if (options->use_pam == -1)
142 options->use_pam = 0;
144 /* Standard Options */
145 if (options->protocol == SSH_PROTO_UNKNOWN)
146 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
147 if (options->num_host_key_files == 0) {
148 /* fill default hostkeys for protocols */
149 if (options->protocol & SSH_PROTO_1)
150 options->host_key_files[options->num_host_key_files++] =
152 if (options->protocol & SSH_PROTO_2) {
153 options->host_key_files[options->num_host_key_files++] =
154 _PATH_HOST_RSA_KEY_FILE;
155 options->host_key_files[options->num_host_key_files++] =
156 _PATH_HOST_DSA_KEY_FILE;
159 if (options->num_ports == 0)
160 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
161 if (options->listen_addrs == NULL)
162 add_listen_addr(options, NULL, 0);
163 if (options->pid_file == NULL)
164 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
165 if (options->server_key_bits == -1)
166 options->server_key_bits = 768;
167 if (options->login_grace_time == -1)
168 options->login_grace_time = 120;
169 if (options->key_regeneration_time == -1)
170 options->key_regeneration_time = 3600;
171 if (options->permit_root_login == PERMIT_NOT_SET)
172 options->permit_root_login = PERMIT_YES;
173 if (options->ignore_rhosts == -1)
174 options->ignore_rhosts = 1;
175 if (options->ignore_user_known_hosts == -1)
176 options->ignore_user_known_hosts = 0;
177 if (options->print_motd == -1)
178 options->print_motd = 1;
179 if (options->print_lastlog == -1)
180 options->print_lastlog = 1;
181 if (options->x11_forwarding == -1)
182 options->x11_forwarding = 0;
183 if (options->x11_display_offset == -1)
184 options->x11_display_offset = 10;
185 if (options->x11_use_localhost == -1)
186 options->x11_use_localhost = 1;
187 if (options->xauth_location == NULL)
188 options->xauth_location = _PATH_XAUTH;
189 if (options->strict_modes == -1)
190 options->strict_modes = 1;
191 if (options->tcp_keep_alive == -1)
192 options->tcp_keep_alive = 1;
193 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
194 options->log_facility = SYSLOG_FACILITY_AUTH;
195 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
196 options->log_level = SYSLOG_LEVEL_INFO;
197 if (options->rhosts_rsa_authentication == -1)
198 options->rhosts_rsa_authentication = 0;
199 if (options->hostbased_authentication == -1)
200 options->hostbased_authentication = 0;
201 if (options->hostbased_uses_name_from_packet_only == -1)
202 options->hostbased_uses_name_from_packet_only = 0;
203 if (options->rsa_authentication == -1)
204 options->rsa_authentication = 1;
205 if (options->pubkey_authentication == -1)
206 options->pubkey_authentication = 1;
207 if (options->kerberos_authentication == -1)
208 options->kerberos_authentication = 0;
209 if (options->kerberos_or_local_passwd == -1)
210 options->kerberos_or_local_passwd = 1;
211 if (options->kerberos_ticket_cleanup == -1)
212 options->kerberos_ticket_cleanup = 1;
213 if (options->kerberos_get_afs_token == -1)
214 options->kerberos_get_afs_token = 0;
215 if (options->gss_authentication == -1)
216 options->gss_authentication = 0;
217 if (options->gss_keyex == -1)
218 options->gss_keyex = 0;
219 if (options->gss_cleanup_creds == -1)
220 options->gss_cleanup_creds = 1;
221 if (options->gss_strict_acceptor == -1)
222 options->gss_strict_acceptor = 1;
223 if (options->password_authentication == -1)
224 options->password_authentication = 1;
225 if (options->kbd_interactive_authentication == -1)
226 options->kbd_interactive_authentication = 0;
227 if (options->challenge_response_authentication == -1)
228 options->challenge_response_authentication = 1;
229 if (options->permit_empty_passwd == -1)
230 options->permit_empty_passwd = 0;
231 if (options->permit_user_env == -1)
232 options->permit_user_env = 0;
233 if (options->use_login == -1)
234 options->use_login = 0;
235 if (options->compression == -1)
236 options->compression = COMP_DELAYED;
237 if (options->allow_tcp_forwarding == -1)
238 options->allow_tcp_forwarding = 1;
239 if (options->gateway_ports == -1)
240 options->gateway_ports = 0;
241 if (options->max_startups == -1)
242 options->max_startups = 10;
243 if (options->max_startups_rate == -1)
244 options->max_startups_rate = 100; /* 100% */
245 if (options->max_startups_begin == -1)
246 options->max_startups_begin = options->max_startups;
247 if (options->max_authtries == -1)
248 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
249 if (options->use_dns == -1)
250 options->use_dns = 1;
251 if (options->client_alive_interval == -1)
252 options->client_alive_interval = 0;
253 if (options->client_alive_count_max == -1)
254 options->client_alive_count_max = 3;
255 if (options->authorized_keys_file2 == NULL) {
256 /* authorized_keys_file2 falls back to authorized_keys_file */
257 if (options->authorized_keys_file != NULL)
258 options->authorized_keys_file2 = options->authorized_keys_file;
260 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
262 if (options->authorized_keys_file == NULL)
263 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
264 if (options->permit_tun == -1)
265 options->permit_tun = SSH_TUNMODE_NO;
267 if (options->hpn_disabled == -1)
268 options->hpn_disabled = 0;
270 if (options->hpn_buffer_size == -1)
272 /* option not explicitly set. Now we have to figure out */
273 /* what value to use */
274 if (options->hpn_disabled == 1)
276 options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
280 /* get the current RCV size and set it to that */
281 /*create a socket but don't connect it */
282 /* we use that the get the rcv socket size */
283 sock = socket(AF_INET, SOCK_STREAM, 0);
284 getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
285 &socksize, &socksizelen);
287 options->hpn_buffer_size = socksize;
288 debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
294 /* we have to do this incase the user sets both values in a contradictory */
295 /* manner. hpn_disabled overrrides hpn_buffer_size*/
296 if (options->hpn_disabled <= 0)
298 if (options->hpn_buffer_size == 0)
299 options->hpn_buffer_size = 1;
300 /* limit the maximum buffer to 64MB */
301 if (options->hpn_buffer_size > 64*1024)
302 options->hpn_buffer_size = 64*1024;
303 options->hpn_buffer_size *=1024;
306 options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
309 /* Turn privilege separation on by default */
310 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,
338 sPasswordAuthentication, sKbdInteractiveAuthentication,
339 sListenAddress, sAddressFamily,
340 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
341 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
342 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
343 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
344 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
345 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
346 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
347 sMaxStartups, sMaxAuthTries,
348 sBanner, sUseDNS, sHostbasedAuthentication,
349 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
350 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
351 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
353 sAcceptEnv, sPermitTunnel,
354 sMatch, sPermitOpen, sForceCommand,
355 sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll,
356 sHPNDisabled, sHPNBufferSize,
357 sDeprecated, sUnsupported
360 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
361 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
362 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
364 /* Textual representation of the tokens. */
367 ServerOpCodes opcode;
370 /* Portable-specific options */
372 { "usepam", sUsePAM, SSHCFG_GLOBAL },
374 { "usepam", sUnsupported, SSHCFG_GLOBAL },
376 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
377 /* Standard Options */
378 { "port", sPort, SSHCFG_GLOBAL },
379 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
380 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
381 { "pidfile", sPidFile, SSHCFG_GLOBAL },
382 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
383 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
384 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
385 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
386 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
387 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
388 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
389 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
390 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
391 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
392 { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
393 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
394 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
396 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
397 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
398 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
400 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
402 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
405 { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
406 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
407 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
408 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
410 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
411 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
413 { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
414 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
415 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
416 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
418 { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
419 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
420 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
421 { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
423 { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
424 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
425 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
426 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
427 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
428 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
429 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
430 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
431 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
432 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
433 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
434 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
435 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
436 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
437 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
438 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
439 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
440 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
441 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
442 { "compression", sCompression, SSHCFG_GLOBAL },
443 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
444 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
445 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
446 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
447 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
448 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
449 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
450 { "ciphers", sCiphers, SSHCFG_GLOBAL },
451 { "macs", sMacs, SSHCFG_GLOBAL },
452 { "protocol", sProtocol, SSHCFG_GLOBAL },
453 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
454 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
455 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
456 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
457 { "banner", sBanner, SSHCFG_GLOBAL },
458 { "usedns", sUseDNS, SSHCFG_GLOBAL },
459 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
460 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
461 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
462 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
463 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
464 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
465 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
466 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
467 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
468 { "match", sMatch, SSHCFG_ALL },
469 { "permitopen", sPermitOpen, SSHCFG_ALL },
470 { "forcecommand", sForceCommand, SSHCFG_ALL },
471 { "noneenabled", sNoneEnabled },
472 { "hpndisabled", sHPNDisabled },
473 { "hpnbuffersize", sHPNBufferSize },
474 { "tcprcvbufpoll", sTcpRcvBufPoll },
475 { NULL, sBadOption, 0 }
479 * Returns the number of the token pointed to by cp or sBadOption.
483 parse_token(const char *cp, const char *filename,
484 int linenum, u_int *flags)
488 for (i = 0; keywords[i].name; i++)
489 if (strcasecmp(cp, keywords[i].name) == 0) {
490 debug ("Config token is %s", keywords[i].name);
491 *flags = keywords[i].flags;
492 return keywords[i].opcode;
495 error("%s: line %d: Bad configuration option: %s",
496 filename, linenum, cp);
501 add_listen_addr(ServerOptions *options, char *addr, u_short port)
505 if (options->num_ports == 0)
506 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
507 if (options->address_family == -1)
508 options->address_family = AF_UNSPEC;
510 for (i = 0; i < options->num_ports; i++)
511 add_one_listen_addr(options, addr, options->ports[i]);
513 add_one_listen_addr(options, addr, port);
517 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
519 struct addrinfo hints, *ai, *aitop;
520 char strport[NI_MAXSERV];
523 memset(&hints, 0, sizeof(hints));
524 hints.ai_family = options->address_family;
525 hints.ai_socktype = SOCK_STREAM;
526 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
527 snprintf(strport, sizeof strport, "%u", port);
528 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
529 fatal("bad addr or host: %s (%s)",
530 addr ? addr : "<NULL>",
531 gai_strerror(gaierr));
532 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
534 ai->ai_next = options->listen_addrs;
535 options->listen_addrs = aitop;
539 * The strategy for the Match blocks is that the config file is parsed twice.
541 * The first time is at startup. activep is initialized to 1 and the
542 * directives in the global context are processed and acted on. Hitting a
543 * Match directive unsets activep and the directives inside the block are
544 * checked for syntax only.
546 * The second time is after a connection has been established but before
547 * authentication. activep is initialized to 2 and global config directives
548 * are ignored since they have already been processed. If the criteria in a
549 * Match block is met, activep is set and the subsequent directives
550 * processed and actioned until EOF or another Match block unsets it. Any
551 * options set are copied into the main server config.
553 * Potential additions/improvements:
554 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
556 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
557 * Match Address 192.168.0.*
562 * AllowTcpForwarding yes
563 * GatewayPorts clientspecified
566 * - Add a PermittedChannelRequests directive
568 * PermittedChannelRequests session,forwarded-tcpip
572 match_cfg_line_group(const char *grps, int line, const char *user)
576 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
580 * Even if we do not have a user yet, we still need to check for
583 arg = cp = xstrdup(grps);
584 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
585 if (ngrps >= MAX_MATCH_GROUPS) {
586 error("line %d: too many groups in Match Group", line);
590 grplist[ngrps++] = p;
596 if ((pw = getpwnam(user)) == NULL) {
597 debug("Can't match group at line %d because user %.100s does "
598 "not exist", line, user);
599 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
600 debug("Can't Match group because user %.100s not in any group "
601 "at line %d", user, line);
602 } else if (ga_match(grplist, ngrps) != 1) {
603 debug("user %.100s does not match group %.100s at line %d",
606 debug("user %.100s matched group %.100s at line %d", user,
617 match_cfg_line(char **condition, int line, const char *user, const char *host,
621 char *arg, *attrib, *cp = *condition;
625 debug3("checking syntax for 'Match %s'", cp);
627 debug3("checking match for '%s' user %s host %s addr %s", cp,
628 user ? user : "(null)", host ? host : "(null)",
629 address ? address : "(null)");
631 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
632 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
633 error("Missing Match criteria for %s", attrib);
637 if (strcasecmp(attrib, "user") == 0) {
642 if (match_pattern_list(user, arg, len, 0) != 1)
645 debug("user %.100s matched 'User %.100s' at "
646 "line %d", user, arg, line);
647 } else if (strcasecmp(attrib, "group") == 0) {
648 switch (match_cfg_line_group(arg, line, user)) {
654 } else if (strcasecmp(attrib, "host") == 0) {
659 if (match_hostname(host, arg, len) != 1)
662 debug("connection from %.100s matched 'Host "
663 "%.100s' at line %d", host, arg, line);
664 } else if (strcasecmp(attrib, "address") == 0) {
665 debug("address '%s' arg '%s'", address, arg);
670 if (match_hostname(address, arg, len) != 1)
673 debug("connection from %.100s matched 'Address "
674 "%.100s' at line %d", address, arg, line);
676 error("Unsupported Match attribute %s", attrib);
681 debug3("match %sfound", result ? "" : "not ");
686 #define WHITESPACE " \t\r\n"
689 process_server_config_line(ServerOptions *options, char *line,
690 const char *filename, int linenum, int *activep, const char *user,
691 const char *host, const char *address)
693 char *cp, **charptr, *arg, *p;
694 int cmdline = 0, *intptr, value, n;
695 ServerOpCodes opcode;
701 if ((arg = strdelim(&cp)) == NULL)
703 /* Ignore leading whitespace */
706 if (!arg || !*arg || *arg == '#')
710 opcode = parse_token(arg, filename, linenum, &flags);
712 if (activep == NULL) { /* We are processing a command line directive */
716 if (*activep && opcode != sMatch)
717 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
718 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
720 fatal("%s line %d: Directive '%s' is not allowed "
721 "within a Match block", filename, linenum, arg);
722 } else { /* this is a directive we have already processed */
730 /* Portable-specific options */
732 intptr = &options->use_pam;
735 /* Standard Options */
739 /* ignore ports from configfile if cmdline specifies ports */
740 if (options->ports_from_cmdline)
742 if (options->listen_addrs != NULL)
743 fatal("%s line %d: ports must be specified before "
744 "ListenAddress.", filename, linenum);
745 if (options->num_ports >= MAX_PORTS)
746 fatal("%s line %d: too many ports.",
749 if (!arg || *arg == '\0')
750 fatal("%s line %d: missing port number.",
752 options->ports[options->num_ports++] = a2port(arg);
753 if (options->ports[options->num_ports-1] == 0)
754 fatal("%s line %d: Badly formatted port number.",
759 intptr = &options->server_key_bits;
762 if (!arg || *arg == '\0')
763 fatal("%s line %d: missing integer value.",
766 if (*activep && *intptr == -1)
770 case sLoginGraceTime:
771 intptr = &options->login_grace_time;
774 if (!arg || *arg == '\0')
775 fatal("%s line %d: missing time value.",
777 if ((value = convtime(arg)) == -1)
778 fatal("%s line %d: invalid time value.",
784 case sKeyRegenerationTime:
785 intptr = &options->key_regeneration_time;
790 if (arg == NULL || *arg == '\0')
791 fatal("%s line %d: missing address",
793 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
794 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
795 && strchr(p+1, ':') != NULL) {
796 add_listen_addr(options, arg, 0);
801 fatal("%s line %d: bad address:port usage",
803 p = cleanhostname(p);
806 else if ((port = a2port(arg)) == 0)
807 fatal("%s line %d: bad port number", filename, linenum);
809 add_listen_addr(options, p, port);
815 if (!arg || *arg == '\0')
816 fatal("%s line %d: missing address family.",
818 intptr = &options->address_family;
819 if (options->listen_addrs != NULL)
820 fatal("%s line %d: address family must be specified before "
821 "ListenAddress.", filename, linenum);
822 if (strcasecmp(arg, "inet") == 0)
824 else if (strcasecmp(arg, "inet6") == 0)
826 else if (strcasecmp(arg, "any") == 0)
829 fatal("%s line %d: unsupported address family \"%s\".",
830 filename, linenum, arg);
836 intptr = &options->num_host_key_files;
837 if (*intptr >= MAX_HOSTKEYS)
838 fatal("%s line %d: too many host keys specified (max %d).",
839 filename, linenum, MAX_HOSTKEYS);
840 charptr = &options->host_key_files[*intptr];
843 if (!arg || *arg == '\0')
844 fatal("%s line %d: missing file name.",
846 if (*activep && *charptr == NULL) {
847 *charptr = tilde_expand_filename(arg, getuid());
848 /* increase optional counter */
850 *intptr = *intptr + 1;
855 charptr = &options->pid_file;
858 case sPermitRootLogin:
859 intptr = &options->permit_root_login;
861 if (!arg || *arg == '\0')
862 fatal("%s line %d: missing yes/"
863 "without-password/forced-commands-only/no "
864 "argument.", filename, linenum);
865 value = 0; /* silence compiler */
866 if (strcmp(arg, "without-password") == 0)
867 value = PERMIT_NO_PASSWD;
868 else if (strcmp(arg, "forced-commands-only") == 0)
869 value = PERMIT_FORCED_ONLY;
870 else if (strcmp(arg, "yes") == 0)
872 else if (strcmp(arg, "no") == 0)
875 fatal("%s line %d: Bad yes/"
876 "without-password/forced-commands-only/no "
877 "argument: %s", filename, linenum, arg);
883 intptr = &options->ignore_rhosts;
886 if (!arg || *arg == '\0')
887 fatal("%s line %d: missing yes/no argument.",
889 value = 0; /* silence compiler */
890 if (strcmp(arg, "yes") == 0)
892 else if (strcmp(arg, "no") == 0)
895 fatal("%s line %d: Bad yes/no argument: %s",
896 filename, linenum, arg);
897 if (*activep && *intptr == -1)
902 intptr = &options->none_enabled;
906 intptr = &options->tcp_rcv_buf_poll;
910 intptr = &options->hpn_disabled;
914 intptr = &options->hpn_buffer_size;
917 case sIgnoreUserKnownHosts:
918 intptr = &options->ignore_user_known_hosts;
921 case sRhostsRSAAuthentication:
922 intptr = &options->rhosts_rsa_authentication;
925 case sHostbasedAuthentication:
926 intptr = &options->hostbased_authentication;
929 case sHostbasedUsesNameFromPacketOnly:
930 intptr = &options->hostbased_uses_name_from_packet_only;
933 case sRSAAuthentication:
934 intptr = &options->rsa_authentication;
937 case sPubkeyAuthentication:
938 intptr = &options->pubkey_authentication;
941 case sKerberosAuthentication:
942 intptr = &options->kerberos_authentication;
945 case sKerberosOrLocalPasswd:
946 intptr = &options->kerberos_or_local_passwd;
949 case sKerberosTicketCleanup:
950 intptr = &options->kerberos_ticket_cleanup;
953 case sKerberosGetAFSToken:
954 intptr = &options->kerberos_get_afs_token;
957 case sGssAuthentication:
958 intptr = &options->gss_authentication;
962 intptr = &options->gss_keyex;
965 case sGssCleanupCreds:
966 intptr = &options->gss_cleanup_creds;
969 case sGssStrictAcceptor:
970 intptr = &options->gss_strict_acceptor;
973 case sPasswordAuthentication:
974 intptr = &options->password_authentication;
977 case sKbdInteractiveAuthentication:
978 intptr = &options->kbd_interactive_authentication;
981 case sChallengeResponseAuthentication:
982 intptr = &options->challenge_response_authentication;
986 intptr = &options->print_motd;
990 intptr = &options->print_lastlog;
994 intptr = &options->x11_forwarding;
997 case sX11DisplayOffset:
998 intptr = &options->x11_display_offset;
1001 case sX11UseLocalhost:
1002 intptr = &options->x11_use_localhost;
1005 case sXAuthLocation:
1006 charptr = &options->xauth_location;
1007 goto parse_filename;
1010 intptr = &options->strict_modes;
1014 intptr = &options->tcp_keep_alive;
1018 intptr = &options->permit_empty_passwd;
1021 case sPermitUserEnvironment:
1022 intptr = &options->permit_user_env;
1026 intptr = &options->use_login;
1030 intptr = &options->compression;
1031 arg = strdelim(&cp);
1032 if (!arg || *arg == '\0')
1033 fatal("%s line %d: missing yes/no/delayed "
1034 "argument.", filename, linenum);
1035 value = 0; /* silence compiler */
1036 if (strcmp(arg, "delayed") == 0)
1037 value = COMP_DELAYED;
1038 else if (strcmp(arg, "yes") == 0)
1040 else if (strcmp(arg, "no") == 0)
1043 fatal("%s line %d: Bad yes/no/delayed "
1044 "argument: %s", filename, linenum, arg);
1050 intptr = &options->gateway_ports;
1051 arg = strdelim(&cp);
1052 if (!arg || *arg == '\0')
1053 fatal("%s line %d: missing yes/no/clientspecified "
1054 "argument.", filename, linenum);
1055 value = 0; /* silence compiler */
1056 if (strcmp(arg, "clientspecified") == 0)
1058 else if (strcmp(arg, "yes") == 0)
1060 else if (strcmp(arg, "no") == 0)
1063 fatal("%s line %d: Bad yes/no/clientspecified "
1064 "argument: %s", filename, linenum, arg);
1070 intptr = &options->use_dns;
1074 intptr = (int *) &options->log_facility;
1075 arg = strdelim(&cp);
1076 value = log_facility_number(arg);
1077 if (value == SYSLOG_FACILITY_NOT_SET)
1078 fatal("%.200s line %d: unsupported log facility '%s'",
1079 filename, linenum, arg ? arg : "<NONE>");
1081 *intptr = (SyslogFacility) value;
1085 intptr = (int *) &options->log_level;
1086 arg = strdelim(&cp);
1087 value = log_level_number(arg);
1088 if (value == SYSLOG_LEVEL_NOT_SET)
1089 fatal("%.200s line %d: unsupported log level '%s'",
1090 filename, linenum, arg ? arg : "<NONE>");
1092 *intptr = (LogLevel) value;
1095 case sAllowTcpForwarding:
1096 intptr = &options->allow_tcp_forwarding;
1099 case sUsePrivilegeSeparation:
1100 intptr = &use_privsep;
1104 while ((arg = strdelim(&cp)) && *arg != '\0') {
1105 if (options->num_allow_users >= MAX_ALLOW_USERS)
1106 fatal("%s line %d: too many allow users.",
1108 options->allow_users[options->num_allow_users++] =
1114 while ((arg = strdelim(&cp)) && *arg != '\0') {
1115 if (options->num_deny_users >= MAX_DENY_USERS)
1116 fatal("%s line %d: too many deny users.",
1118 options->deny_users[options->num_deny_users++] =
1124 while ((arg = strdelim(&cp)) && *arg != '\0') {
1125 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1126 fatal("%s line %d: too many allow groups.",
1128 options->allow_groups[options->num_allow_groups++] =
1134 while ((arg = strdelim(&cp)) && *arg != '\0') {
1135 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1136 fatal("%s line %d: too many deny groups.",
1138 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1143 arg = strdelim(&cp);
1144 if (!arg || *arg == '\0')
1145 fatal("%s line %d: Missing argument.", filename, linenum);
1146 if (!ciphers_valid(arg))
1147 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1148 filename, linenum, arg ? arg : "<NONE>");
1149 if (options->ciphers == NULL)
1150 options->ciphers = xstrdup(arg);
1154 arg = strdelim(&cp);
1155 if (!arg || *arg == '\0')
1156 fatal("%s line %d: Missing argument.", filename, linenum);
1157 if (!mac_valid(arg))
1158 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1159 filename, linenum, arg ? arg : "<NONE>");
1160 if (options->macs == NULL)
1161 options->macs = xstrdup(arg);
1165 intptr = &options->protocol;
1166 arg = strdelim(&cp);
1167 if (!arg || *arg == '\0')
1168 fatal("%s line %d: Missing argument.", filename, linenum);
1169 value = proto_spec(arg);
1170 if (value == SSH_PROTO_UNKNOWN)
1171 fatal("%s line %d: Bad protocol spec '%s'.",
1172 filename, linenum, arg ? arg : "<NONE>");
1173 if (*intptr == SSH_PROTO_UNKNOWN)
1178 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1179 fatal("%s line %d: too many subsystems defined.",
1182 arg = strdelim(&cp);
1183 if (!arg || *arg == '\0')
1184 fatal("%s line %d: Missing subsystem name.",
1187 arg = strdelim(&cp);
1190 for (i = 0; i < options->num_subsystems; i++)
1191 if (strcmp(arg, options->subsystem_name[i]) == 0)
1192 fatal("%s line %d: Subsystem '%s' already defined.",
1193 filename, linenum, arg);
1194 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1195 arg = strdelim(&cp);
1196 if (!arg || *arg == '\0')
1197 fatal("%s line %d: Missing subsystem command.",
1199 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1201 /* Collect arguments (separate to executable) */
1203 len = strlen(p) + 1;
1204 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1205 len += 1 + strlen(arg);
1206 p = xrealloc(p, 1, len);
1207 strlcat(p, " ", len);
1208 strlcat(p, arg, len);
1210 options->subsystem_args[options->num_subsystems] = p;
1211 options->num_subsystems++;
1215 arg = strdelim(&cp);
1216 if (!arg || *arg == '\0')
1217 fatal("%s line %d: Missing MaxStartups spec.",
1219 if ((n = sscanf(arg, "%d:%d:%d",
1220 &options->max_startups_begin,
1221 &options->max_startups_rate,
1222 &options->max_startups)) == 3) {
1223 if (options->max_startups_begin >
1224 options->max_startups ||
1225 options->max_startups_rate > 100 ||
1226 options->max_startups_rate < 1)
1227 fatal("%s line %d: Illegal MaxStartups spec.",
1230 fatal("%s line %d: Illegal MaxStartups spec.",
1233 options->max_startups = options->max_startups_begin;
1237 intptr = &options->max_authtries;
1241 charptr = &options->banner;
1242 goto parse_filename;
1244 * These options can contain %X options expanded at
1245 * connect time, so that you can specify paths like:
1247 * AuthorizedKeysFile /etc/ssh_keys/%u
1249 case sAuthorizedKeysFile:
1250 case sAuthorizedKeysFile2:
1251 charptr = (opcode == sAuthorizedKeysFile) ?
1252 &options->authorized_keys_file :
1253 &options->authorized_keys_file2;
1254 goto parse_filename;
1256 case sClientAliveInterval:
1257 intptr = &options->client_alive_interval;
1260 case sClientAliveCountMax:
1261 intptr = &options->client_alive_count_max;
1265 while ((arg = strdelim(&cp)) && *arg != '\0') {
1266 if (strchr(arg, '=') != NULL)
1267 fatal("%s line %d: Invalid environment name.",
1269 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1270 fatal("%s line %d: too many allow env.",
1274 options->accept_env[options->num_accept_env++] =
1280 intptr = &options->permit_tun;
1281 arg = strdelim(&cp);
1282 if (!arg || *arg == '\0')
1283 fatal("%s line %d: Missing yes/point-to-point/"
1284 "ethernet/no argument.", filename, linenum);
1285 value = 0; /* silence compiler */
1286 if (strcasecmp(arg, "ethernet") == 0)
1287 value = SSH_TUNMODE_ETHERNET;
1288 else if (strcasecmp(arg, "point-to-point") == 0)
1289 value = SSH_TUNMODE_POINTOPOINT;
1290 else if (strcasecmp(arg, "yes") == 0)
1291 value = SSH_TUNMODE_YES;
1292 else if (strcasecmp(arg, "no") == 0)
1293 value = SSH_TUNMODE_NO;
1295 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1296 "no argument: %s", filename, linenum, arg);
1303 fatal("Match directive not supported as a command-line "
1305 value = match_cfg_line(&cp, linenum, user, host, address);
1307 fatal("%s line %d: Bad Match condition", filename,
1313 arg = strdelim(&cp);
1314 if (!arg || *arg == '\0')
1315 fatal("%s line %d: missing PermitOpen specification",
1317 if (strcmp(arg, "any") == 0) {
1319 channel_clear_adm_permitted_opens();
1320 options->num_permitted_opens = 0;
1324 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1327 fatal("%s line %d: missing host in PermitOpen",
1329 p = cleanhostname(p);
1330 if (arg == NULL || (port = a2port(arg)) == 0)
1331 fatal("%s line %d: bad port number in "
1332 "PermitOpen", filename, linenum);
1333 if (*activep && options->num_permitted_opens == -1) {
1334 channel_clear_adm_permitted_opens();
1335 options->num_permitted_opens =
1336 channel_add_adm_permitted_opens(p, port);
1343 fatal("%.200s line %d: Missing argument.", filename,
1345 len = strspn(cp, WHITESPACE);
1346 if (*activep && options->adm_forced_command == NULL)
1347 options->adm_forced_command = xstrdup(cp + len);
1351 logit("%s line %d: Deprecated option %s",
1352 filename, linenum, arg);
1354 arg = strdelim(&cp);
1358 logit("%s line %d: Unsupported option %s",
1359 filename, linenum, arg);
1361 arg = strdelim(&cp);
1365 fatal("%s line %d: Missing handler for opcode %s (%d)",
1366 filename, linenum, arg, opcode);
1368 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1369 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1370 filename, linenum, arg);
1374 /* Reads the server configuration file. */
1377 load_server_config(const char *filename, Buffer *conf)
1379 char line[1024], *cp;
1382 debug2("%s: filename %s", __func__, filename);
1383 if ((f = fopen(filename, "r")) == NULL) {
1388 while (fgets(line, sizeof(line), f)) {
1390 * Trim out comments and strip whitespace
1391 * NB - preserve newlines, they are needed to reproduce
1392 * line numbers later for error messages
1394 if ((cp = strchr(line, '#')) != NULL)
1395 memcpy(cp, "\n", 2);
1396 cp = line + strspn(line, " \t\r");
1398 buffer_append(conf, cp, strlen(cp));
1400 buffer_append(conf, "\0", 1);
1402 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1406 parse_server_match_config(ServerOptions *options, const char *user,
1407 const char *host, const char *address)
1411 initialize_server_options(&mo);
1412 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1413 copy_set_server_options(options, &mo);
1416 /* Copy any (supported) values that are set */
1418 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1420 if (src->allow_tcp_forwarding != -1)
1421 dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1422 if (src->gateway_ports != -1)
1423 dst->gateway_ports = src->gateway_ports;
1424 if (src->adm_forced_command != NULL) {
1425 if (dst->adm_forced_command != NULL)
1426 xfree(dst->adm_forced_command);
1427 dst->adm_forced_command = src->adm_forced_command;
1429 if (src->x11_display_offset != -1)
1430 dst->x11_display_offset = src->x11_display_offset;
1431 if (src->x11_forwarding != -1)
1432 dst->x11_forwarding = src->x11_forwarding;
1433 if (src->x11_use_localhost != -1)
1434 dst->x11_use_localhost = src->x11_use_localhost;
1438 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1439 const char *user, const char *host, const char *address)
1441 int active, linenum, bad_options = 0;
1442 char *cp, *obuf, *cbuf;
1444 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1446 obuf = cbuf = xstrdup(buffer_ptr(conf));
1447 active = user ? 0 : 1;
1449 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1450 if (process_server_config_line(options, cp, filename,
1451 linenum++, &active, user, host, address) != 0)
1455 if (bad_options > 0)
1456 fatal("%s: terminating, %d bad configuration options",
1457 filename, bad_options);