1 /* $OpenBSD: servconf.c,v 1.179 2008/05/08 12:02:23 djm Exp $ */
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
15 #include <sys/types.h>
16 #include <sys/socket.h>
27 #include "openbsd-compat/sys-queue.h"
34 #include "pathnames.h"
42 #include "groupaccess.h"
44 static void add_listen_addr(ServerOptions *, char *, u_short);
45 static void add_one_listen_addr(ServerOptions *, char *, u_short);
47 /* Use of privilege separation or not */
48 extern int use_privsep;
51 /* Initializes the server options to their default values. */
54 initialize_server_options(ServerOptions *options)
56 memset(options, 0, sizeof(*options));
58 /* Portable-specific options */
59 options->use_pam = -1;
61 /* Standard Options */
62 options->num_ports = 0;
63 options->ports_from_cmdline = 0;
64 options->listen_addrs = NULL;
65 options->address_family = -1;
66 options->num_host_key_files = 0;
67 options->pid_file = NULL;
68 options->server_key_bits = -1;
69 options->login_grace_time = -1;
70 options->key_regeneration_time = -1;
71 options->permit_root_login = PERMIT_NOT_SET;
72 options->ignore_rhosts = -1;
73 options->ignore_user_known_hosts = -1;
74 options->print_motd = -1;
75 options->print_lastlog = -1;
76 options->x11_forwarding = -1;
77 options->x11_display_offset = -1;
78 options->x11_use_localhost = -1;
79 options->xauth_location = NULL;
80 options->strict_modes = -1;
81 options->tcp_keep_alive = -1;
82 options->log_facility = SYSLOG_FACILITY_NOT_SET;
83 options->log_level = SYSLOG_LEVEL_NOT_SET;
84 options->rhosts_rsa_authentication = -1;
85 options->hostbased_authentication = -1;
86 options->hostbased_uses_name_from_packet_only = -1;
87 options->rsa_authentication = -1;
88 options->pubkey_authentication = -1;
89 options->kerberos_authentication = -1;
90 options->kerberos_or_local_passwd = -1;
91 options->kerberos_ticket_cleanup = -1;
92 options->kerberos_get_afs_token = -1;
93 options->gss_authentication=-1;
94 options->gss_cleanup_creds = -1;
95 options->password_authentication = -1;
96 options->kbd_interactive_authentication = -1;
97 options->challenge_response_authentication = -1;
98 options->permit_empty_passwd = -1;
99 options->permit_user_env = -1;
100 options->use_login = -1;
101 options->compression = -1;
102 options->allow_tcp_forwarding = -1;
103 options->allow_agent_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->chroot_directory = NULL;
131 fill_default_server_options(ServerOptions *options)
133 /* Portable-specific options */
134 if (options->use_pam == -1)
135 options->use_pam = 0;
137 /* Standard Options */
138 if (options->protocol == SSH_PROTO_UNKNOWN)
139 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
140 if (options->num_host_key_files == 0) {
141 /* fill default hostkeys for protocols */
142 if (options->protocol & SSH_PROTO_1)
143 options->host_key_files[options->num_host_key_files++] =
145 if (options->protocol & SSH_PROTO_2) {
146 options->host_key_files[options->num_host_key_files++] =
147 _PATH_HOST_RSA_KEY_FILE;
148 options->host_key_files[options->num_host_key_files++] =
149 _PATH_HOST_DSA_KEY_FILE;
152 if (options->num_ports == 0)
153 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
154 if (options->listen_addrs == NULL)
155 add_listen_addr(options, NULL, 0);
156 if (options->pid_file == NULL)
157 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
158 if (options->server_key_bits == -1)
159 options->server_key_bits = 768;
160 if (options->login_grace_time == -1)
161 options->login_grace_time = 120;
162 if (options->key_regeneration_time == -1)
163 options->key_regeneration_time = 3600;
164 if (options->permit_root_login == PERMIT_NOT_SET)
165 options->permit_root_login = PERMIT_YES;
166 if (options->ignore_rhosts == -1)
167 options->ignore_rhosts = 1;
168 if (options->ignore_user_known_hosts == -1)
169 options->ignore_user_known_hosts = 0;
170 if (options->print_motd == -1)
171 options->print_motd = 1;
172 if (options->print_lastlog == -1)
173 options->print_lastlog = 1;
174 if (options->x11_forwarding == -1)
175 options->x11_forwarding = 0;
176 if (options->x11_display_offset == -1)
177 options->x11_display_offset = 10;
178 if (options->x11_use_localhost == -1)
179 options->x11_use_localhost = 1;
180 if (options->xauth_location == NULL)
181 options->xauth_location = _PATH_XAUTH;
182 if (options->strict_modes == -1)
183 options->strict_modes = 1;
184 if (options->tcp_keep_alive == -1)
185 options->tcp_keep_alive = 1;
186 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
187 options->log_facility = SYSLOG_FACILITY_AUTH;
188 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
189 options->log_level = SYSLOG_LEVEL_INFO;
190 if (options->rhosts_rsa_authentication == -1)
191 options->rhosts_rsa_authentication = 0;
192 if (options->hostbased_authentication == -1)
193 options->hostbased_authentication = 0;
194 if (options->hostbased_uses_name_from_packet_only == -1)
195 options->hostbased_uses_name_from_packet_only = 0;
196 if (options->rsa_authentication == -1)
197 options->rsa_authentication = 1;
198 if (options->pubkey_authentication == -1)
199 options->pubkey_authentication = 1;
200 if (options->kerberos_authentication == -1)
201 options->kerberos_authentication = 0;
202 if (options->kerberos_or_local_passwd == -1)
203 options->kerberos_or_local_passwd = 1;
204 if (options->kerberos_ticket_cleanup == -1)
205 options->kerberos_ticket_cleanup = 1;
206 if (options->kerberos_get_afs_token == -1)
207 options->kerberos_get_afs_token = 0;
208 if (options->gss_authentication == -1)
209 options->gss_authentication = 0;
210 if (options->gss_cleanup_creds == -1)
211 options->gss_cleanup_creds = 1;
212 if (options->password_authentication == -1)
213 options->password_authentication = 1;
214 if (options->kbd_interactive_authentication == -1)
215 options->kbd_interactive_authentication = 0;
216 if (options->challenge_response_authentication == -1)
217 options->challenge_response_authentication = 1;
218 if (options->permit_empty_passwd == -1)
219 options->permit_empty_passwd = 0;
220 if (options->permit_user_env == -1)
221 options->permit_user_env = 0;
222 if (options->use_login == -1)
223 options->use_login = 0;
224 if (options->compression == -1)
225 options->compression = COMP_DELAYED;
226 if (options->allow_tcp_forwarding == -1)
227 options->allow_tcp_forwarding = 1;
228 if (options->allow_agent_forwarding == -1)
229 options->allow_agent_forwarding = 1;
230 if (options->gateway_ports == -1)
231 options->gateway_ports = 0;
232 if (options->max_startups == -1)
233 options->max_startups = 10;
234 if (options->max_startups_rate == -1)
235 options->max_startups_rate = 100; /* 100% */
236 if (options->max_startups_begin == -1)
237 options->max_startups_begin = options->max_startups;
238 if (options->max_authtries == -1)
239 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
240 if (options->use_dns == -1)
241 options->use_dns = 1;
242 if (options->client_alive_interval == -1)
243 options->client_alive_interval = 0;
244 if (options->client_alive_count_max == -1)
245 options->client_alive_count_max = 3;
246 if (options->authorized_keys_file2 == NULL) {
247 /* authorized_keys_file2 falls back to authorized_keys_file */
248 if (options->authorized_keys_file != NULL)
249 options->authorized_keys_file2 = options->authorized_keys_file;
251 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
253 if (options->authorized_keys_file == NULL)
254 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
255 if (options->permit_tun == -1)
256 options->permit_tun = SSH_TUNMODE_NO;
258 /* Turn privilege separation on by default */
259 if (use_privsep == -1)
263 if (use_privsep && options->compression == 1) {
264 error("This platform does not support both privilege "
265 "separation and compression");
266 error("Compression disabled");
267 options->compression = 0;
273 /* Keyword tokens. */
275 sBadOption, /* == unknown option */
276 /* Portable-specific options */
278 /* Standard Options */
279 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
280 sPermitRootLogin, sLogFacility, sLogLevel,
281 sRhostsRSAAuthentication, sRSAAuthentication,
282 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
283 sKerberosGetAFSToken,
284 sKerberosTgtPassing, sChallengeResponseAuthentication,
285 sPasswordAuthentication, sKbdInteractiveAuthentication,
286 sListenAddress, sAddressFamily,
287 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
288 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
289 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
290 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
291 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
292 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
293 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
294 sMaxStartups, sMaxAuthTries,
295 sBanner, sUseDNS, sHostbasedAuthentication,
296 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
297 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
298 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
299 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
300 sUsePrivilegeSeparation, sAllowAgentForwarding,
301 sDeprecated, sUnsupported
304 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
305 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
306 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
308 /* Textual representation of the tokens. */
311 ServerOpCodes opcode;
314 /* Portable-specific options */
316 { "usepam", sUsePAM, SSHCFG_GLOBAL },
318 { "usepam", sUnsupported, SSHCFG_GLOBAL },
320 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
321 /* Standard Options */
322 { "port", sPort, SSHCFG_GLOBAL },
323 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
324 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
325 { "pidfile", sPidFile, SSHCFG_GLOBAL },
326 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
327 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
328 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
329 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
330 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
331 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
332 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
333 { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
334 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
335 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
336 { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
337 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
338 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
340 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
341 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
342 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
344 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
346 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
349 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
350 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
351 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
352 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
354 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
355 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
357 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
358 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
360 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
361 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
363 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
364 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
365 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
366 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
367 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
368 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
369 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
370 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
371 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
372 { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
373 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
374 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
375 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
376 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
377 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
378 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
379 { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
380 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
381 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
382 { "compression", sCompression, SSHCFG_GLOBAL },
383 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
384 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
385 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
386 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
387 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
388 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
389 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
390 { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
391 { "ciphers", sCiphers, SSHCFG_GLOBAL },
392 { "macs", sMacs, SSHCFG_GLOBAL },
393 { "protocol", sProtocol, SSHCFG_GLOBAL },
394 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
395 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
396 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
397 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
398 { "banner", sBanner, SSHCFG_ALL },
399 { "usedns", sUseDNS, SSHCFG_GLOBAL },
400 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
401 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
402 { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
403 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
404 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
405 { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
406 { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
407 { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
408 { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
409 { "match", sMatch, SSHCFG_ALL },
410 { "permitopen", sPermitOpen, SSHCFG_ALL },
411 { "forcecommand", sForceCommand, SSHCFG_ALL },
412 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
413 { NULL, sBadOption, 0 }
417 * Returns the number of the token pointed to by cp or sBadOption.
421 parse_token(const char *cp, const char *filename,
422 int linenum, u_int *flags)
426 for (i = 0; keywords[i].name; i++)
427 if (strcasecmp(cp, keywords[i].name) == 0) {
428 *flags = keywords[i].flags;
429 return keywords[i].opcode;
432 error("%s: line %d: Bad configuration option: %s",
433 filename, linenum, cp);
438 add_listen_addr(ServerOptions *options, char *addr, u_short port)
442 if (options->num_ports == 0)
443 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
444 if (options->address_family == -1)
445 options->address_family = AF_UNSPEC;
447 for (i = 0; i < options->num_ports; i++)
448 add_one_listen_addr(options, addr, options->ports[i]);
450 add_one_listen_addr(options, addr, port);
454 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
456 struct addrinfo hints, *ai, *aitop;
457 char strport[NI_MAXSERV];
460 memset(&hints, 0, sizeof(hints));
461 hints.ai_family = options->address_family;
462 hints.ai_socktype = SOCK_STREAM;
463 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
464 snprintf(strport, sizeof strport, "%u", port);
465 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
466 fatal("bad addr or host: %s (%s)",
467 addr ? addr : "<NULL>",
468 ssh_gai_strerror(gaierr));
469 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
471 ai->ai_next = options->listen_addrs;
472 options->listen_addrs = aitop;
476 * The strategy for the Match blocks is that the config file is parsed twice.
478 * The first time is at startup. activep is initialized to 1 and the
479 * directives in the global context are processed and acted on. Hitting a
480 * Match directive unsets activep and the directives inside the block are
481 * checked for syntax only.
483 * The second time is after a connection has been established but before
484 * authentication. activep is initialized to 2 and global config directives
485 * are ignored since they have already been processed. If the criteria in a
486 * Match block is met, activep is set and the subsequent directives
487 * processed and actioned until EOF or another Match block unsets it. Any
488 * options set are copied into the main server config.
490 * Potential additions/improvements:
491 * - Add Match support for pre-kex directives, eg Protocol, Ciphers.
493 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
494 * Match Address 192.168.0.*
499 * AllowTcpForwarding yes
500 * GatewayPorts clientspecified
503 * - Add a PermittedChannelRequests directive
505 * PermittedChannelRequests session,forwarded-tcpip
509 match_cfg_line_group(const char *grps, int line, const char *user)
513 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
517 * Even if we do not have a user yet, we still need to check for
520 arg = cp = xstrdup(grps);
521 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
522 if (ngrps >= MAX_MATCH_GROUPS) {
523 error("line %d: too many groups in Match Group", line);
527 grplist[ngrps++] = p;
533 if ((pw = getpwnam(user)) == NULL) {
534 debug("Can't match group at line %d because user %.100s does "
535 "not exist", line, user);
536 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
537 debug("Can't Match group because user %.100s not in any group "
538 "at line %d", user, line);
539 } else if (ga_match(grplist, ngrps) != 1) {
540 debug("user %.100s does not match group %.100s at line %d",
543 debug("user %.100s matched group %.100s at line %d", user,
554 match_cfg_line(char **condition, int line, const char *user, const char *host,
558 char *arg, *attrib, *cp = *condition;
562 debug3("checking syntax for 'Match %s'", cp);
564 debug3("checking match for '%s' user %s host %s addr %s", cp,
565 user ? user : "(null)", host ? host : "(null)",
566 address ? address : "(null)");
568 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
569 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
570 error("Missing Match criteria for %s", attrib);
574 if (strcasecmp(attrib, "user") == 0) {
579 if (match_pattern_list(user, arg, len, 0) != 1)
582 debug("user %.100s matched 'User %.100s' at "
583 "line %d", user, arg, line);
584 } else if (strcasecmp(attrib, "group") == 0) {
585 switch (match_cfg_line_group(arg, line, user)) {
591 } else if (strcasecmp(attrib, "host") == 0) {
596 if (match_hostname(host, arg, len) != 1)
599 debug("connection from %.100s matched 'Host "
600 "%.100s' at line %d", host, arg, line);
601 } else if (strcasecmp(attrib, "address") == 0) {
606 if (match_hostname(address, arg, len) != 1)
609 debug("connection from %.100s matched 'Address "
610 "%.100s' at line %d", address, arg, line);
612 error("Unsupported Match attribute %s", attrib);
617 debug3("match %sfound", result ? "" : "not ");
622 #define WHITESPACE " \t\r\n"
625 process_server_config_line(ServerOptions *options, char *line,
626 const char *filename, int linenum, int *activep, const char *user,
627 const char *host, const char *address)
629 char *cp, **charptr, *arg, *p;
630 int cmdline = 0, *intptr, value, n;
631 SyslogFacility *log_facility_ptr;
632 LogLevel *log_level_ptr;
633 ServerOpCodes opcode;
639 if ((arg = strdelim(&cp)) == NULL)
641 /* Ignore leading whitespace */
644 if (!arg || !*arg || *arg == '#')
648 opcode = parse_token(arg, filename, linenum, &flags);
650 if (activep == NULL) { /* We are processing a command line directive */
654 if (*activep && opcode != sMatch)
655 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
656 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
658 fatal("%s line %d: Directive '%s' is not allowed "
659 "within a Match block", filename, linenum, arg);
660 } else { /* this is a directive we have already processed */
668 /* Portable-specific options */
670 intptr = &options->use_pam;
673 /* Standard Options */
677 /* ignore ports from configfile if cmdline specifies ports */
678 if (options->ports_from_cmdline)
680 if (options->listen_addrs != NULL)
681 fatal("%s line %d: ports must be specified before "
682 "ListenAddress.", filename, linenum);
683 if (options->num_ports >= MAX_PORTS)
684 fatal("%s line %d: too many ports.",
687 if (!arg || *arg == '\0')
688 fatal("%s line %d: missing port number.",
690 options->ports[options->num_ports++] = a2port(arg);
691 if (options->ports[options->num_ports-1] == 0)
692 fatal("%s line %d: Badly formatted port number.",
697 intptr = &options->server_key_bits;
700 if (!arg || *arg == '\0')
701 fatal("%s line %d: missing integer value.",
704 if (*activep && *intptr == -1)
708 case sLoginGraceTime:
709 intptr = &options->login_grace_time;
712 if (!arg || *arg == '\0')
713 fatal("%s line %d: missing time value.",
715 if ((value = convtime(arg)) == -1)
716 fatal("%s line %d: invalid time value.",
722 case sKeyRegenerationTime:
723 intptr = &options->key_regeneration_time;
728 if (arg == NULL || *arg == '\0')
729 fatal("%s line %d: missing address",
731 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
732 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
733 && strchr(p+1, ':') != NULL) {
734 add_listen_addr(options, arg, 0);
739 fatal("%s line %d: bad address:port usage",
741 p = cleanhostname(p);
744 else if ((port = a2port(arg)) == 0)
745 fatal("%s line %d: bad port number", filename, linenum);
747 add_listen_addr(options, p, port);
753 if (!arg || *arg == '\0')
754 fatal("%s line %d: missing address family.",
756 intptr = &options->address_family;
757 if (options->listen_addrs != NULL)
758 fatal("%s line %d: address family must be specified before "
759 "ListenAddress.", filename, linenum);
760 if (strcasecmp(arg, "inet") == 0)
762 else if (strcasecmp(arg, "inet6") == 0)
764 else if (strcasecmp(arg, "any") == 0)
767 fatal("%s line %d: unsupported address family \"%s\".",
768 filename, linenum, arg);
774 intptr = &options->num_host_key_files;
775 if (*intptr >= MAX_HOSTKEYS)
776 fatal("%s line %d: too many host keys specified (max %d).",
777 filename, linenum, MAX_HOSTKEYS);
778 charptr = &options->host_key_files[*intptr];
781 if (!arg || *arg == '\0')
782 fatal("%s line %d: missing file name.",
784 if (*activep && *charptr == NULL) {
785 *charptr = tilde_expand_filename(arg, getuid());
786 /* increase optional counter */
788 *intptr = *intptr + 1;
793 charptr = &options->pid_file;
796 case sPermitRootLogin:
797 intptr = &options->permit_root_login;
799 if (!arg || *arg == '\0')
800 fatal("%s line %d: missing yes/"
801 "without-password/forced-commands-only/no "
802 "argument.", filename, linenum);
803 value = 0; /* silence compiler */
804 if (strcmp(arg, "without-password") == 0)
805 value = PERMIT_NO_PASSWD;
806 else if (strcmp(arg, "forced-commands-only") == 0)
807 value = PERMIT_FORCED_ONLY;
808 else if (strcmp(arg, "yes") == 0)
810 else if (strcmp(arg, "no") == 0)
813 fatal("%s line %d: Bad yes/"
814 "without-password/forced-commands-only/no "
815 "argument: %s", filename, linenum, arg);
816 if (*activep && *intptr == -1)
821 intptr = &options->ignore_rhosts;
824 if (!arg || *arg == '\0')
825 fatal("%s line %d: missing yes/no argument.",
827 value = 0; /* silence compiler */
828 if (strcmp(arg, "yes") == 0)
830 else if (strcmp(arg, "no") == 0)
833 fatal("%s line %d: Bad yes/no argument: %s",
834 filename, linenum, arg);
835 if (*activep && *intptr == -1)
839 case sIgnoreUserKnownHosts:
840 intptr = &options->ignore_user_known_hosts;
843 case sRhostsRSAAuthentication:
844 intptr = &options->rhosts_rsa_authentication;
847 case sHostbasedAuthentication:
848 intptr = &options->hostbased_authentication;
851 case sHostbasedUsesNameFromPacketOnly:
852 intptr = &options->hostbased_uses_name_from_packet_only;
855 case sRSAAuthentication:
856 intptr = &options->rsa_authentication;
859 case sPubkeyAuthentication:
860 intptr = &options->pubkey_authentication;
863 case sKerberosAuthentication:
864 intptr = &options->kerberos_authentication;
867 case sKerberosOrLocalPasswd:
868 intptr = &options->kerberos_or_local_passwd;
871 case sKerberosTicketCleanup:
872 intptr = &options->kerberos_ticket_cleanup;
875 case sKerberosGetAFSToken:
876 intptr = &options->kerberos_get_afs_token;
879 case sGssAuthentication:
880 intptr = &options->gss_authentication;
883 case sGssCleanupCreds:
884 intptr = &options->gss_cleanup_creds;
887 case sPasswordAuthentication:
888 intptr = &options->password_authentication;
891 case sKbdInteractiveAuthentication:
892 intptr = &options->kbd_interactive_authentication;
895 case sChallengeResponseAuthentication:
896 intptr = &options->challenge_response_authentication;
900 intptr = &options->print_motd;
904 intptr = &options->print_lastlog;
908 intptr = &options->x11_forwarding;
911 case sX11DisplayOffset:
912 intptr = &options->x11_display_offset;
915 case sX11UseLocalhost:
916 intptr = &options->x11_use_localhost;
920 charptr = &options->xauth_location;
924 intptr = &options->strict_modes;
928 intptr = &options->tcp_keep_alive;
932 intptr = &options->permit_empty_passwd;
935 case sPermitUserEnvironment:
936 intptr = &options->permit_user_env;
940 intptr = &options->use_login;
944 intptr = &options->compression;
946 if (!arg || *arg == '\0')
947 fatal("%s line %d: missing yes/no/delayed "
948 "argument.", filename, linenum);
949 value = 0; /* silence compiler */
950 if (strcmp(arg, "delayed") == 0)
951 value = COMP_DELAYED;
952 else if (strcmp(arg, "yes") == 0)
954 else if (strcmp(arg, "no") == 0)
957 fatal("%s line %d: Bad yes/no/delayed "
958 "argument: %s", filename, linenum, arg);
964 intptr = &options->gateway_ports;
966 if (!arg || *arg == '\0')
967 fatal("%s line %d: missing yes/no/clientspecified "
968 "argument.", filename, linenum);
969 value = 0; /* silence compiler */
970 if (strcmp(arg, "clientspecified") == 0)
972 else if (strcmp(arg, "yes") == 0)
974 else if (strcmp(arg, "no") == 0)
977 fatal("%s line %d: Bad yes/no/clientspecified "
978 "argument: %s", filename, linenum, arg);
979 if (*activep && *intptr == -1)
984 intptr = &options->use_dns;
988 log_facility_ptr = &options->log_facility;
990 value = log_facility_number(arg);
991 if (value == SYSLOG_FACILITY_NOT_SET)
992 fatal("%.200s line %d: unsupported log facility '%s'",
993 filename, linenum, arg ? arg : "<NONE>");
994 if (*log_facility_ptr == -1)
995 *log_facility_ptr = (SyslogFacility) value;
999 log_level_ptr = &options->log_level;
1000 arg = strdelim(&cp);
1001 value = log_level_number(arg);
1002 if (value == SYSLOG_LEVEL_NOT_SET)
1003 fatal("%.200s line %d: unsupported log level '%s'",
1004 filename, linenum, arg ? arg : "<NONE>");
1005 if (*log_level_ptr == -1)
1006 *log_level_ptr = (LogLevel) value;
1009 case sAllowTcpForwarding:
1010 intptr = &options->allow_tcp_forwarding;
1013 case sAllowAgentForwarding:
1014 intptr = &options->allow_agent_forwarding;
1017 case sUsePrivilegeSeparation:
1018 intptr = &use_privsep;
1022 while ((arg = strdelim(&cp)) && *arg != '\0') {
1023 if (options->num_allow_users >= MAX_ALLOW_USERS)
1024 fatal("%s line %d: too many allow users.",
1026 options->allow_users[options->num_allow_users++] =
1032 while ((arg = strdelim(&cp)) && *arg != '\0') {
1033 if (options->num_deny_users >= MAX_DENY_USERS)
1034 fatal("%s line %d: too many deny users.",
1036 options->deny_users[options->num_deny_users++] =
1042 while ((arg = strdelim(&cp)) && *arg != '\0') {
1043 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1044 fatal("%s line %d: too many allow groups.",
1046 options->allow_groups[options->num_allow_groups++] =
1052 while ((arg = strdelim(&cp)) && *arg != '\0') {
1053 if (options->num_deny_groups >= MAX_DENY_GROUPS)
1054 fatal("%s line %d: too many deny groups.",
1056 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1061 arg = strdelim(&cp);
1062 if (!arg || *arg == '\0')
1063 fatal("%s line %d: Missing argument.", filename, linenum);
1064 if (!ciphers_valid(arg))
1065 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1066 filename, linenum, arg ? arg : "<NONE>");
1067 if (options->ciphers == NULL)
1068 options->ciphers = xstrdup(arg);
1072 arg = strdelim(&cp);
1073 if (!arg || *arg == '\0')
1074 fatal("%s line %d: Missing argument.", filename, linenum);
1075 if (!mac_valid(arg))
1076 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1077 filename, linenum, arg ? arg : "<NONE>");
1078 if (options->macs == NULL)
1079 options->macs = xstrdup(arg);
1083 intptr = &options->protocol;
1084 arg = strdelim(&cp);
1085 if (!arg || *arg == '\0')
1086 fatal("%s line %d: Missing argument.", filename, linenum);
1087 value = proto_spec(arg);
1088 if (value == SSH_PROTO_UNKNOWN)
1089 fatal("%s line %d: Bad protocol spec '%s'.",
1090 filename, linenum, arg ? arg : "<NONE>");
1091 if (*intptr == SSH_PROTO_UNKNOWN)
1096 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1097 fatal("%s line %d: too many subsystems defined.",
1100 arg = strdelim(&cp);
1101 if (!arg || *arg == '\0')
1102 fatal("%s line %d: Missing subsystem name.",
1105 arg = strdelim(&cp);
1108 for (i = 0; i < options->num_subsystems; i++)
1109 if (strcmp(arg, options->subsystem_name[i]) == 0)
1110 fatal("%s line %d: Subsystem '%s' already defined.",
1111 filename, linenum, arg);
1112 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1113 arg = strdelim(&cp);
1114 if (!arg || *arg == '\0')
1115 fatal("%s line %d: Missing subsystem command.",
1117 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1119 /* Collect arguments (separate to executable) */
1121 len = strlen(p) + 1;
1122 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1123 len += 1 + strlen(arg);
1124 p = xrealloc(p, 1, len);
1125 strlcat(p, " ", len);
1126 strlcat(p, arg, len);
1128 options->subsystem_args[options->num_subsystems] = p;
1129 options->num_subsystems++;
1133 arg = strdelim(&cp);
1134 if (!arg || *arg == '\0')
1135 fatal("%s line %d: Missing MaxStartups spec.",
1137 if ((n = sscanf(arg, "%d:%d:%d",
1138 &options->max_startups_begin,
1139 &options->max_startups_rate,
1140 &options->max_startups)) == 3) {
1141 if (options->max_startups_begin >
1142 options->max_startups ||
1143 options->max_startups_rate > 100 ||
1144 options->max_startups_rate < 1)
1145 fatal("%s line %d: Illegal MaxStartups spec.",
1148 fatal("%s line %d: Illegal MaxStartups spec.",
1151 options->max_startups = options->max_startups_begin;
1155 intptr = &options->max_authtries;
1159 charptr = &options->banner;
1160 goto parse_filename;
1163 * These options can contain %X options expanded at
1164 * connect time, so that you can specify paths like:
1166 * AuthorizedKeysFile /etc/ssh_keys/%u
1168 case sAuthorizedKeysFile:
1169 case sAuthorizedKeysFile2:
1170 charptr = (opcode == sAuthorizedKeysFile) ?
1171 &options->authorized_keys_file :
1172 &options->authorized_keys_file2;
1173 goto parse_filename;
1175 case sClientAliveInterval:
1176 intptr = &options->client_alive_interval;
1179 case sClientAliveCountMax:
1180 intptr = &options->client_alive_count_max;
1184 while ((arg = strdelim(&cp)) && *arg != '\0') {
1185 if (strchr(arg, '=') != NULL)
1186 fatal("%s line %d: Invalid environment name.",
1188 if (options->num_accept_env >= MAX_ACCEPT_ENV)
1189 fatal("%s line %d: too many allow env.",
1193 options->accept_env[options->num_accept_env++] =
1199 intptr = &options->permit_tun;
1200 arg = strdelim(&cp);
1201 if (!arg || *arg == '\0')
1202 fatal("%s line %d: Missing yes/point-to-point/"
1203 "ethernet/no argument.", filename, linenum);
1204 value = 0; /* silence compiler */
1205 if (strcasecmp(arg, "ethernet") == 0)
1206 value = SSH_TUNMODE_ETHERNET;
1207 else if (strcasecmp(arg, "point-to-point") == 0)
1208 value = SSH_TUNMODE_POINTOPOINT;
1209 else if (strcasecmp(arg, "yes") == 0)
1210 value = SSH_TUNMODE_YES;
1211 else if (strcasecmp(arg, "no") == 0)
1212 value = SSH_TUNMODE_NO;
1214 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1215 "no argument: %s", filename, linenum, arg);
1222 fatal("Match directive not supported as a command-line "
1224 value = match_cfg_line(&cp, linenum, user, host, address);
1226 fatal("%s line %d: Bad Match condition", filename,
1232 arg = strdelim(&cp);
1233 if (!arg || *arg == '\0')
1234 fatal("%s line %d: missing PermitOpen specification",
1236 n = options->num_permitted_opens; /* modified later */
1237 if (strcmp(arg, "any") == 0) {
1238 if (*activep && n == -1) {
1239 channel_clear_adm_permitted_opens();
1240 options->num_permitted_opens = 0;
1244 if (*activep && n == -1)
1245 channel_clear_adm_permitted_opens();
1246 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1249 fatal("%s line %d: missing host in PermitOpen",
1251 p = cleanhostname(p);
1252 if (arg == NULL || (port = a2port(arg)) == 0)
1253 fatal("%s line %d: bad port number in "
1254 "PermitOpen", filename, linenum);
1255 if (*activep && n == -1)
1256 options->num_permitted_opens =
1257 channel_add_adm_permitted_opens(p, port);
1263 fatal("%.200s line %d: Missing argument.", filename,
1265 len = strspn(cp, WHITESPACE);
1266 if (*activep && options->adm_forced_command == NULL)
1267 options->adm_forced_command = xstrdup(cp + len);
1270 case sChrootDirectory:
1271 charptr = &options->chroot_directory;
1273 arg = strdelim(&cp);
1274 if (!arg || *arg == '\0')
1275 fatal("%s line %d: missing file name.",
1277 if (*activep && *charptr == NULL)
1278 *charptr = xstrdup(arg);
1282 logit("%s line %d: Deprecated option %s",
1283 filename, linenum, arg);
1285 arg = strdelim(&cp);
1289 logit("%s line %d: Unsupported option %s",
1290 filename, linenum, arg);
1292 arg = strdelim(&cp);
1296 fatal("%s line %d: Missing handler for opcode %s (%d)",
1297 filename, linenum, arg, opcode);
1299 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1300 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1301 filename, linenum, arg);
1305 /* Reads the server configuration file. */
1308 load_server_config(const char *filename, Buffer *conf)
1310 char line[1024], *cp;
1313 debug2("%s: filename %s", __func__, filename);
1314 if ((f = fopen(filename, "r")) == NULL) {
1319 while (fgets(line, sizeof(line), f)) {
1321 * Trim out comments and strip whitespace
1322 * NB - preserve newlines, they are needed to reproduce
1323 * line numbers later for error messages
1325 if ((cp = strchr(line, '#')) != NULL)
1326 memcpy(cp, "\n", 2);
1327 cp = line + strspn(line, " \t\r");
1329 buffer_append(conf, cp, strlen(cp));
1331 buffer_append(conf, "\0", 1);
1333 debug2("%s: done config len = %d", __func__, buffer_len(conf));
1337 parse_server_match_config(ServerOptions *options, const char *user,
1338 const char *host, const char *address)
1342 initialize_server_options(&mo);
1343 parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1344 copy_set_server_options(options, &mo, 0);
1348 #define M_CP_INTOPT(n) do {\
1352 #define M_CP_STROPT(n) do {\
1353 if (src->n != NULL) { \
1354 if (dst->n != NULL) \
1361 * Copy any supported values that are set.
1363 * If the preauth flag is set, we do not bother copying the the string or
1364 * array values that are not used pre-authentication, because any that we
1365 * do use must be explictly sent in mm_getpwnamallow().
1368 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1370 M_CP_INTOPT(password_authentication);
1371 M_CP_INTOPT(gss_authentication);
1372 M_CP_INTOPT(rsa_authentication);
1373 M_CP_INTOPT(pubkey_authentication);
1374 M_CP_INTOPT(kerberos_authentication);
1375 M_CP_INTOPT(hostbased_authentication);
1376 M_CP_INTOPT(kbd_interactive_authentication);
1377 M_CP_INTOPT(permit_root_login);
1379 M_CP_INTOPT(allow_tcp_forwarding);
1380 M_CP_INTOPT(allow_agent_forwarding);
1381 M_CP_INTOPT(gateway_ports);
1382 M_CP_INTOPT(x11_display_offset);
1383 M_CP_INTOPT(x11_forwarding);
1384 M_CP_INTOPT(x11_use_localhost);
1386 M_CP_STROPT(banner);
1389 M_CP_STROPT(adm_forced_command);
1390 M_CP_STROPT(chroot_directory);
1397 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1398 const char *user, const char *host, const char *address)
1400 int active, linenum, bad_options = 0;
1401 char *cp, *obuf, *cbuf;
1403 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1405 obuf = cbuf = xstrdup(buffer_ptr(conf));
1406 active = user ? 0 : 1;
1408 while ((cp = strsep(&cbuf, "\n")) != NULL) {
1409 if (process_server_config_line(options, cp, filename,
1410 linenum++, &active, user, host, address) != 0)
1414 if (bad_options > 0)
1415 fatal("%s: terminating, %d bad configuration options",
1416 filename, bad_options);