inet6: only mark autoconf addresses tentative if detached
[dragonfly.git] / crypto / openssh / servconf.c
blob66822fb3e0ece9f64346a54786dadff94d62418f
2 /* $OpenBSD: servconf.c,v 1.386 2022/09/17 10:34:29 djm Exp $ */
3 /*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose. Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
14 #include "includes.h"
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <sys/stat.h>
19 #ifdef __OpenBSD__
20 #include <sys/sysctl.h>
21 #endif
23 #include <netinet/in.h>
24 #include <netinet/in_systm.h>
25 #include <netinet/ip.h>
26 #ifdef HAVE_NET_ROUTE_H
27 #include <net/route.h>
28 #endif
30 #include <ctype.h>
31 #include <netdb.h>
32 #include <pwd.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <signal.h>
37 #include <unistd.h>
38 #include <limits.h>
39 #include <stdarg.h>
40 #include <errno.h>
41 #ifdef HAVE_UTIL_H
42 #include <util.h>
43 #endif
44 #ifdef USE_SYSTEM_GLOB
45 # include <glob.h>
46 #else
47 # include "openbsd-compat/glob.h"
48 #endif
50 #include "openbsd-compat/sys-queue.h"
51 #include "xmalloc.h"
52 #include "ssh.h"
53 #include "log.h"
54 #include "sshbuf.h"
55 #include "misc.h"
56 #include "servconf.h"
57 #include "compat.h"
58 #include "pathnames.h"
59 #include "cipher.h"
60 #include "sshkey.h"
61 #include "kex.h"
62 #include "mac.h"
63 #include "match.h"
64 #include "channels.h"
65 #include "groupaccess.h"
66 #include "canohost.h"
67 #include "packet.h"
68 #include "ssherr.h"
69 #include "hostfile.h"
70 #include "auth.h"
71 #include "myproposal.h"
72 #include "digest.h"
74 static void add_listen_addr(ServerOptions *, const char *,
75 const char *, int);
76 static void add_one_listen_addr(ServerOptions *, const char *,
77 const char *, int);
78 static void parse_server_config_depth(ServerOptions *options,
79 const char *filename, struct sshbuf *conf, struct include_list *includes,
80 struct connection_info *connectinfo, int flags, int *activep, int depth);
82 /* Use of privilege separation or not */
83 extern int use_privsep;
84 extern struct sshbuf *cfg;
86 /* Initializes the server options to their default values. */
88 void
89 initialize_server_options(ServerOptions *options)
91 memset(options, 0, sizeof(*options));
93 /* Portable-specific options */
94 options->use_pam = -1;
96 /* Standard Options */
97 options->num_ports = 0;
98 options->ports_from_cmdline = 0;
99 options->queued_listen_addrs = NULL;
100 options->num_queued_listens = 0;
101 options->listen_addrs = NULL;
102 options->num_listen_addrs = 0;
103 options->address_family = -1;
104 options->routing_domain = NULL;
105 options->num_host_key_files = 0;
106 options->num_host_cert_files = 0;
107 options->host_key_agent = NULL;
108 options->pid_file = NULL;
109 options->login_grace_time = -1;
110 options->permit_root_login = PERMIT_NOT_SET;
111 options->ignore_rhosts = -1;
112 options->ignore_user_known_hosts = -1;
113 options->print_motd = -1;
114 options->print_lastlog = -1;
115 options->x11_forwarding = -1;
116 options->x11_display_offset = -1;
117 options->x11_use_localhost = -1;
118 options->permit_tty = -1;
119 options->permit_user_rc = -1;
120 options->xauth_location = NULL;
121 options->strict_modes = -1;
122 options->tcp_keep_alive = -1;
123 options->log_facility = SYSLOG_FACILITY_NOT_SET;
124 options->log_level = SYSLOG_LEVEL_NOT_SET;
125 options->num_log_verbose = 0;
126 options->log_verbose = NULL;
127 options->hostbased_authentication = -1;
128 options->hostbased_uses_name_from_packet_only = -1;
129 options->hostbased_accepted_algos = NULL;
130 options->hostkeyalgorithms = NULL;
131 options->pubkey_authentication = -1;
132 options->pubkey_auth_options = -1;
133 options->pubkey_accepted_algos = NULL;
134 options->kerberos_authentication = -1;
135 options->kerberos_or_local_passwd = -1;
136 options->kerberos_ticket_cleanup = -1;
137 options->kerberos_get_afs_token = -1;
138 options->gss_authentication=-1;
139 options->gss_cleanup_creds = -1;
140 options->gss_strict_acceptor = -1;
141 options->password_authentication = -1;
142 options->kbd_interactive_authentication = -1;
143 options->permit_empty_passwd = -1;
144 options->permit_user_env = -1;
145 options->permit_user_env_allowlist = NULL;
146 options->compression = -1;
147 options->rekey_limit = -1;
148 options->rekey_interval = -1;
149 options->allow_tcp_forwarding = -1;
150 options->allow_streamlocal_forwarding = -1;
151 options->allow_agent_forwarding = -1;
152 options->num_allow_users = 0;
153 options->num_deny_users = 0;
154 options->num_allow_groups = 0;
155 options->num_deny_groups = 0;
156 options->ciphers = NULL;
157 options->macs = NULL;
158 options->kex_algorithms = NULL;
159 options->ca_sign_algorithms = NULL;
160 options->fwd_opts.gateway_ports = -1;
161 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
162 options->fwd_opts.streamlocal_bind_unlink = -1;
163 options->num_subsystems = 0;
164 options->max_startups_begin = -1;
165 options->max_startups_rate = -1;
166 options->max_startups = -1;
167 options->per_source_max_startups = -1;
168 options->per_source_masklen_ipv4 = -1;
169 options->per_source_masklen_ipv6 = -1;
170 options->max_authtries = -1;
171 options->max_sessions = -1;
172 options->banner = NULL;
173 options->use_dns = -1;
174 options->client_alive_interval = -1;
175 options->client_alive_count_max = -1;
176 options->num_authkeys_files = 0;
177 options->num_accept_env = 0;
178 options->num_setenv = 0;
179 options->permit_tun = -1;
180 options->permitted_opens = NULL;
181 options->permitted_listens = NULL;
182 options->adm_forced_command = NULL;
183 options->chroot_directory = NULL;
184 options->authorized_keys_command = NULL;
185 options->authorized_keys_command_user = NULL;
186 options->revoked_keys_file = NULL;
187 options->sk_provider = NULL;
188 options->trusted_user_ca_keys = NULL;
189 options->authorized_principals_file = NULL;
190 options->authorized_principals_command = NULL;
191 options->authorized_principals_command_user = NULL;
192 options->ip_qos_interactive = -1;
193 options->ip_qos_bulk = -1;
194 options->version_addendum = NULL;
195 options->fingerprint_hash = -1;
196 options->disable_forwarding = -1;
197 options->expose_userauth_info = -1;
198 options->required_rsa_size = -1;
201 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
202 static int
203 option_clear_or_none(const char *o)
205 return o == NULL || strcasecmp(o, "none") == 0;
208 static void
209 assemble_algorithms(ServerOptions *o)
211 char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
212 char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
213 int r;
215 all_cipher = cipher_alg_list(',', 0);
216 all_mac = mac_alg_list(',');
217 all_kex = kex_alg_list(',');
218 all_key = sshkey_alg_list(0, 0, 1, ',');
219 all_sig = sshkey_alg_list(0, 1, 1, ',');
220 /* remove unsupported algos from default lists */
221 def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
222 def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
223 def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
224 def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
225 def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
226 #define ASSEMBLE(what, defaults, all) \
227 do { \
228 if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
229 fatal_fr(r, "%s", #what); \
230 } while (0)
231 ASSEMBLE(ciphers, def_cipher, all_cipher);
232 ASSEMBLE(macs, def_mac, all_mac);
233 ASSEMBLE(kex_algorithms, def_kex, all_kex);
234 ASSEMBLE(hostkeyalgorithms, def_key, all_key);
235 ASSEMBLE(hostbased_accepted_algos, def_key, all_key);
236 ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
237 ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
238 #undef ASSEMBLE
239 free(all_cipher);
240 free(all_mac);
241 free(all_kex);
242 free(all_key);
243 free(all_sig);
244 free(def_cipher);
245 free(def_mac);
246 free(def_kex);
247 free(def_key);
248 free(def_sig);
251 void
252 servconf_add_hostkey(const char *file, const int line,
253 ServerOptions *options, const char *path, int userprovided)
255 char *apath = derelativise_path(path);
257 opt_array_append2(file, line, "HostKey",
258 &options->host_key_files, &options->host_key_file_userprovided,
259 &options->num_host_key_files, apath, userprovided);
260 free(apath);
263 void
264 servconf_add_hostcert(const char *file, const int line,
265 ServerOptions *options, const char *path)
267 char *apath = derelativise_path(path);
269 opt_array_append(file, line, "HostCertificate",
270 &options->host_cert_files, &options->num_host_cert_files, apath);
271 free(apath);
274 void
275 fill_default_server_options(ServerOptions *options)
277 u_int i;
280 * Portable-specific options.
282 * Please do NOT under any circumstances change the default to 1,
283 * for any reason. The use of PAM is not considered to be secure
284 * by default.
286 if (options->use_pam == -1)
287 options->use_pam = 0;
289 /* Standard Options */
290 if (options->num_host_key_files == 0) {
291 /* fill default hostkeys for protocols */
292 servconf_add_hostkey("[default]", 0, options,
293 _PATH_HOST_RSA_KEY_FILE, 0);
294 #ifdef OPENSSL_HAS_ECC
295 servconf_add_hostkey("[default]", 0, options,
296 _PATH_HOST_ECDSA_KEY_FILE, 0);
297 #endif
298 servconf_add_hostkey("[default]", 0, options,
299 _PATH_HOST_ED25519_KEY_FILE, 0);
300 #ifdef WITH_XMSS
301 servconf_add_hostkey("[default]", 0, options,
302 _PATH_HOST_XMSS_KEY_FILE, 0);
303 #endif /* WITH_XMSS */
305 /* No certificates by default */
306 if (options->num_ports == 0)
307 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
308 if (options->address_family == -1)
309 options->address_family = AF_UNSPEC;
310 if (options->listen_addrs == NULL)
311 add_listen_addr(options, NULL, NULL, 0);
312 if (options->pid_file == NULL)
313 options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
314 if (options->moduli_file == NULL)
315 options->moduli_file = xstrdup(_PATH_DH_MODULI);
316 if (options->login_grace_time == -1)
317 options->login_grace_time = 120;
318 if (options->permit_root_login == PERMIT_NOT_SET)
319 options->permit_root_login = PERMIT_NO_PASSWD;
320 if (options->ignore_rhosts == -1)
321 options->ignore_rhosts = 1;
322 if (options->ignore_user_known_hosts == -1)
323 options->ignore_user_known_hosts = 0;
324 if (options->print_motd == -1)
325 options->print_motd = 1;
326 if (options->print_lastlog == -1)
327 options->print_lastlog = 1;
328 if (options->x11_forwarding == -1)
329 options->x11_forwarding = 0;
330 if (options->x11_display_offset == -1)
331 options->x11_display_offset = 10;
332 if (options->x11_use_localhost == -1)
333 options->x11_use_localhost = 1;
334 if (options->xauth_location == NULL)
335 options->xauth_location = xstrdup(_PATH_XAUTH);
336 if (options->permit_tty == -1)
337 options->permit_tty = 1;
338 if (options->permit_user_rc == -1)
339 options->permit_user_rc = 1;
340 if (options->strict_modes == -1)
341 options->strict_modes = 1;
342 if (options->tcp_keep_alive == -1)
343 options->tcp_keep_alive = 1;
344 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
345 options->log_facility = SYSLOG_FACILITY_AUTH;
346 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
347 options->log_level = SYSLOG_LEVEL_INFO;
348 if (options->hostbased_authentication == -1)
349 options->hostbased_authentication = 0;
350 if (options->hostbased_uses_name_from_packet_only == -1)
351 options->hostbased_uses_name_from_packet_only = 0;
352 if (options->pubkey_authentication == -1)
353 options->pubkey_authentication = 1;
354 if (options->pubkey_auth_options == -1)
355 options->pubkey_auth_options = 0;
356 if (options->kerberos_authentication == -1)
357 options->kerberos_authentication = 0;
358 if (options->kerberos_or_local_passwd == -1)
359 options->kerberos_or_local_passwd = 1;
360 if (options->kerberos_ticket_cleanup == -1)
361 options->kerberos_ticket_cleanup = 1;
362 if (options->kerberos_get_afs_token == -1)
363 options->kerberos_get_afs_token = 0;
364 if (options->gss_authentication == -1)
365 options->gss_authentication = 0;
366 if (options->gss_cleanup_creds == -1)
367 options->gss_cleanup_creds = 1;
368 if (options->gss_strict_acceptor == -1)
369 options->gss_strict_acceptor = 1;
371 * Please do NOT under any circumstances change the default to 1,
372 * for any reason. The use of plaintext passwords are not considered
373 * secure by default.
375 if (options->password_authentication == -1)
376 options->password_authentication = 0;
377 if (options->kbd_interactive_authentication == -1)
378 options->kbd_interactive_authentication = 1;
379 if (options->permit_empty_passwd == -1)
380 options->permit_empty_passwd = 0;
381 if (options->permit_user_env == -1) {
382 options->permit_user_env = 0;
383 options->permit_user_env_allowlist = NULL;
385 if (options->compression == -1)
386 #ifdef WITH_ZLIB
387 options->compression = COMP_DELAYED;
388 #else
389 options->compression = COMP_NONE;
390 #endif
392 if (options->rekey_limit == -1)
393 options->rekey_limit = 0;
394 if (options->rekey_interval == -1)
395 options->rekey_interval = 0;
396 if (options->allow_tcp_forwarding == -1)
397 options->allow_tcp_forwarding = FORWARD_ALLOW;
398 if (options->allow_streamlocal_forwarding == -1)
399 options->allow_streamlocal_forwarding = FORWARD_ALLOW;
400 if (options->allow_agent_forwarding == -1)
401 options->allow_agent_forwarding = 1;
402 if (options->fwd_opts.gateway_ports == -1)
403 options->fwd_opts.gateway_ports = 0;
404 if (options->max_startups == -1)
405 options->max_startups = 100;
406 if (options->max_startups_rate == -1)
407 options->max_startups_rate = 30; /* 30% */
408 if (options->max_startups_begin == -1)
409 options->max_startups_begin = 10;
410 if (options->per_source_max_startups == -1)
411 options->per_source_max_startups = INT_MAX;
412 if (options->per_source_masklen_ipv4 == -1)
413 options->per_source_masklen_ipv4 = 32;
414 if (options->per_source_masklen_ipv6 == -1)
415 options->per_source_masklen_ipv6 = 128;
416 if (options->max_authtries == -1)
417 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
418 if (options->max_sessions == -1)
419 options->max_sessions = DEFAULT_SESSIONS_MAX;
420 if (options->use_dns == -1)
421 options->use_dns = 0;
422 if (options->client_alive_interval == -1)
423 options->client_alive_interval = 0;
424 if (options->client_alive_count_max == -1)
425 options->client_alive_count_max = 3;
426 if (options->num_authkeys_files == 0) {
427 opt_array_append("[default]", 0, "AuthorizedKeysFiles",
428 &options->authorized_keys_files,
429 &options->num_authkeys_files,
430 _PATH_SSH_USER_PERMITTED_KEYS);
431 opt_array_append("[default]", 0, "AuthorizedKeysFiles",
432 &options->authorized_keys_files,
433 &options->num_authkeys_files,
434 _PATH_SSH_USER_PERMITTED_KEYS2);
436 if (options->permit_tun == -1)
437 options->permit_tun = SSH_TUNMODE_NO;
438 if (options->ip_qos_interactive == -1)
439 options->ip_qos_interactive = IPTOS_DSCP_AF21;
440 if (options->ip_qos_bulk == -1)
441 options->ip_qos_bulk = IPTOS_DSCP_CS1;
442 if (options->version_addendum == NULL)
443 options->version_addendum = xstrdup("");
444 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
445 options->fwd_opts.streamlocal_bind_mask = 0177;
446 if (options->fwd_opts.streamlocal_bind_unlink == -1)
447 options->fwd_opts.streamlocal_bind_unlink = 0;
448 if (options->fingerprint_hash == -1)
449 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
450 if (options->disable_forwarding == -1)
451 options->disable_forwarding = 0;
452 if (options->expose_userauth_info == -1)
453 options->expose_userauth_info = 0;
454 if (options->sk_provider == NULL)
455 options->sk_provider = xstrdup("internal");
456 if (options->required_rsa_size == -1)
457 options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
459 assemble_algorithms(options);
461 /* Turn privilege separation and sandboxing on by default */
462 if (use_privsep == -1)
463 use_privsep = PRIVSEP_ON;
465 #define CLEAR_ON_NONE(v) \
466 do { \
467 if (option_clear_or_none(v)) { \
468 free(v); \
469 v = NULL; \
471 } while(0)
472 CLEAR_ON_NONE(options->pid_file);
473 CLEAR_ON_NONE(options->xauth_location);
474 CLEAR_ON_NONE(options->banner);
475 CLEAR_ON_NONE(options->trusted_user_ca_keys);
476 CLEAR_ON_NONE(options->revoked_keys_file);
477 CLEAR_ON_NONE(options->sk_provider);
478 CLEAR_ON_NONE(options->authorized_principals_file);
479 CLEAR_ON_NONE(options->adm_forced_command);
480 CLEAR_ON_NONE(options->chroot_directory);
481 CLEAR_ON_NONE(options->routing_domain);
482 CLEAR_ON_NONE(options->host_key_agent);
483 for (i = 0; i < options->num_host_key_files; i++)
484 CLEAR_ON_NONE(options->host_key_files[i]);
485 for (i = 0; i < options->num_host_cert_files; i++)
486 CLEAR_ON_NONE(options->host_cert_files[i]);
487 #undef CLEAR_ON_NONE
489 /* Similar handling for AuthenticationMethods=any */
490 if (options->num_auth_methods == 1 &&
491 strcmp(options->auth_methods[0], "any") == 0) {
492 free(options->auth_methods[0]);
493 options->auth_methods[0] = NULL;
494 options->num_auth_methods = 0;
498 /* Keyword tokens. */
499 typedef enum {
500 sBadOption, /* == unknown option */
501 /* Portable-specific options */
502 sUsePAM,
503 /* Standard Options */
504 sPort, sHostKeyFile, sLoginGraceTime,
505 sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
506 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
507 sKerberosGetAFSToken, sPasswordAuthentication,
508 sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
509 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
510 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
511 sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
512 sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
513 sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
514 sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, sModuliFile,
515 sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedAlgorithms,
516 sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
517 sBanner, sUseDNS, sHostbasedAuthentication,
518 sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
519 sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
520 sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
521 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
522 sAcceptEnv, sSetEnv, sPermitTunnel,
523 sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
524 sUsePrivilegeSeparation, sAllowAgentForwarding,
525 sHostCertificate, sInclude,
526 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
527 sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
528 sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
529 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
530 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
531 sStreamLocalBindMask, sStreamLocalBindUnlink,
532 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
533 sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
534 sRequiredRSASize,
535 sDeprecated, sIgnore, sUnsupported
536 } ServerOpCodes;
538 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */
539 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
540 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
541 #define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */
542 #define SSHCFG_MATCH_ONLY 0x08 /* Match only in conditional blocks; internal only */
544 /* Textual representation of the tokens. */
545 static struct {
546 const char *name;
547 ServerOpCodes opcode;
548 u_int flags;
549 } keywords[] = {
550 /* Portable-specific options */
551 #ifdef USE_PAM
552 { "usepam", sUsePAM, SSHCFG_GLOBAL },
553 #else
554 { "usepam", sUnsupported, SSHCFG_GLOBAL },
555 #endif
556 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
557 /* Standard Options */
558 { "port", sPort, SSHCFG_GLOBAL },
559 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
560 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
561 { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
562 { "pidfile", sPidFile, SSHCFG_GLOBAL },
563 { "modulifile", sModuliFile, SSHCFG_GLOBAL },
564 { "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
565 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
566 { "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
567 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
568 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
569 { "loglevel", sLogLevel, SSHCFG_ALL },
570 { "logverbose", sLogVerbose, SSHCFG_ALL },
571 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
572 { "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
573 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
574 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
575 { "hostbasedacceptedalgorithms", sHostbasedAcceptedAlgorithms, SSHCFG_ALL },
576 { "hostbasedacceptedkeytypes", sHostbasedAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
577 { "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
578 { "rsaauthentication", sDeprecated, SSHCFG_ALL },
579 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
580 { "pubkeyacceptedalgorithms", sPubkeyAcceptedAlgorithms, SSHCFG_ALL },
581 { "pubkeyacceptedkeytypes", sPubkeyAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
582 { "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL },
583 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
584 #ifdef KRB5
585 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
586 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
587 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
588 #ifdef USE_AFS
589 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
590 #else
591 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
592 #endif
593 #else
594 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
595 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
596 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
597 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
598 #endif
599 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
600 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
601 #ifdef GSSAPI
602 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
603 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
604 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
605 #else
606 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
607 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
608 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
609 #endif
610 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
611 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
612 { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
613 { "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
614 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
615 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
616 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
617 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
618 #ifdef DISABLE_LASTLOG
619 { "printlastlog", sUnsupported, SSHCFG_GLOBAL },
620 #else
621 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
622 #endif
623 { "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL },
624 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
625 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
626 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
627 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
628 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
629 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
630 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
631 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
632 { "uselogin", sDeprecated, SSHCFG_GLOBAL },
633 { "compression", sCompression, SSHCFG_GLOBAL },
634 { "rekeylimit", sRekeyLimit, SSHCFG_ALL },
635 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
636 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
637 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
638 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
639 { "allowusers", sAllowUsers, SSHCFG_ALL },
640 { "denyusers", sDenyUsers, SSHCFG_ALL },
641 { "allowgroups", sAllowGroups, SSHCFG_ALL },
642 { "denygroups", sDenyGroups, SSHCFG_ALL },
643 { "ciphers", sCiphers, SSHCFG_GLOBAL },
644 { "macs", sMacs, SSHCFG_GLOBAL },
645 { "protocol", sIgnore, SSHCFG_GLOBAL },
646 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
647 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
648 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
649 { "persourcemaxstartups", sPerSourceMaxStartups, SSHCFG_GLOBAL },
650 { "persourcenetblocksize", sPerSourceNetBlockSize, SSHCFG_GLOBAL },
651 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
652 { "maxsessions", sMaxSessions, SSHCFG_ALL },
653 { "banner", sBanner, SSHCFG_ALL },
654 { "usedns", sUseDNS, SSHCFG_GLOBAL },
655 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
656 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
657 { "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
658 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
659 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
660 { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
661 { "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
662 { "acceptenv", sAcceptEnv, SSHCFG_ALL },
663 { "setenv", sSetEnv, SSHCFG_ALL },
664 { "permittunnel", sPermitTunnel, SSHCFG_ALL },
665 { "permittty", sPermitTTY, SSHCFG_ALL },
666 { "permituserrc", sPermitUserRC, SSHCFG_ALL },
667 { "match", sMatch, SSHCFG_ALL },
668 { "permitopen", sPermitOpen, SSHCFG_ALL },
669 { "permitlisten", sPermitListen, SSHCFG_ALL },
670 { "forcecommand", sForceCommand, SSHCFG_ALL },
671 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
672 { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
673 { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
674 { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
675 { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
676 { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
677 { "include", sInclude, SSHCFG_ALL },
678 { "ipqos", sIPQoS, SSHCFG_ALL },
679 { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
680 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
681 { "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
682 { "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
683 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
684 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
685 { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
686 { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
687 { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
688 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
689 { "disableforwarding", sDisableForwarding, SSHCFG_ALL },
690 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
691 { "rdomain", sRDomain, SSHCFG_ALL },
692 { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
693 { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
694 { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
695 { NULL, sBadOption, 0 }
698 static struct {
699 int val;
700 char *text;
701 } tunmode_desc[] = {
702 { SSH_TUNMODE_NO, "no" },
703 { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
704 { SSH_TUNMODE_ETHERNET, "ethernet" },
705 { SSH_TUNMODE_YES, "yes" },
706 { -1, NULL }
709 /* Returns an opcode name from its number */
711 static const char *
712 lookup_opcode_name(ServerOpCodes code)
714 u_int i;
716 for (i = 0; keywords[i].name != NULL; i++)
717 if (keywords[i].opcode == code)
718 return(keywords[i].name);
719 return "UNKNOWN";
724 * Returns the number of the token pointed to by cp or sBadOption.
727 static ServerOpCodes
728 parse_token(const char *cp, const char *filename,
729 int linenum, u_int *flags)
731 u_int i;
733 for (i = 0; keywords[i].name; i++)
734 if (strcasecmp(cp, keywords[i].name) == 0) {
735 *flags = keywords[i].flags;
736 return keywords[i].opcode;
739 error("%s: line %d: Bad configuration option: %s",
740 filename, linenum, cp);
741 return sBadOption;
744 char *
745 derelativise_path(const char *path)
747 char *expanded, *ret, cwd[PATH_MAX];
749 if (strcasecmp(path, "none") == 0)
750 return xstrdup("none");
751 expanded = tilde_expand_filename(path, getuid());
752 if (path_absolute(expanded))
753 return expanded;
754 if (getcwd(cwd, sizeof(cwd)) == NULL)
755 fatal_f("getcwd: %s", strerror(errno));
756 xasprintf(&ret, "%s/%s", cwd, expanded);
757 free(expanded);
758 return ret;
761 static void
762 add_listen_addr(ServerOptions *options, const char *addr,
763 const char *rdomain, int port)
765 u_int i;
767 if (port > 0)
768 add_one_listen_addr(options, addr, rdomain, port);
769 else {
770 for (i = 0; i < options->num_ports; i++) {
771 add_one_listen_addr(options, addr, rdomain,
772 options->ports[i]);
777 static void
778 add_one_listen_addr(ServerOptions *options, const char *addr,
779 const char *rdomain, int port)
781 struct addrinfo hints, *ai, *aitop;
782 char strport[NI_MAXSERV];
783 int gaierr;
784 u_int i;
786 /* Find listen_addrs entry for this rdomain */
787 for (i = 0; i < options->num_listen_addrs; i++) {
788 if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
789 break;
790 if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
791 continue;
792 if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
793 break;
795 if (i >= options->num_listen_addrs) {
796 /* No entry for this rdomain; allocate one */
797 if (i >= INT_MAX)
798 fatal_f("too many listen addresses");
799 options->listen_addrs = xrecallocarray(options->listen_addrs,
800 options->num_listen_addrs, options->num_listen_addrs + 1,
801 sizeof(*options->listen_addrs));
802 i = options->num_listen_addrs++;
803 if (rdomain != NULL)
804 options->listen_addrs[i].rdomain = xstrdup(rdomain);
806 /* options->listen_addrs[i] points to the addresses for this rdomain */
808 memset(&hints, 0, sizeof(hints));
809 hints.ai_family = options->address_family;
810 hints.ai_socktype = SOCK_STREAM;
811 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
812 snprintf(strport, sizeof strport, "%d", port);
813 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
814 fatal("bad addr or host: %s (%s)",
815 addr ? addr : "<NULL>",
816 ssh_gai_strerror(gaierr));
817 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
819 ai->ai_next = options->listen_addrs[i].addrs;
820 options->listen_addrs[i].addrs = aitop;
823 /* Returns nonzero if the routing domain name is valid */
824 static int
825 valid_rdomain(const char *name)
827 #if defined(HAVE_SYS_VALID_RDOMAIN)
828 return sys_valid_rdomain(name);
829 #elif defined(__OpenBSD__)
830 const char *errstr;
831 long long num;
832 struct rt_tableinfo info;
833 int mib[6];
834 size_t miblen = sizeof(mib);
836 if (name == NULL)
837 return 1;
839 num = strtonum(name, 0, 255, &errstr);
840 if (errstr != NULL)
841 return 0;
843 /* Check whether the table actually exists */
844 memset(mib, 0, sizeof(mib));
845 mib[0] = CTL_NET;
846 mib[1] = PF_ROUTE;
847 mib[4] = NET_RT_TABLE;
848 mib[5] = (int)num;
849 if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
850 return 0;
852 return 1;
853 #else /* defined(__OpenBSD__) */
854 error("Routing domains are not supported on this platform");
855 return 0;
856 #endif
860 * Queue a ListenAddress to be processed once we have all of the Ports
861 * and AddressFamily options.
863 static void
864 queue_listen_addr(ServerOptions *options, const char *addr,
865 const char *rdomain, int port)
867 struct queued_listenaddr *qla;
869 options->queued_listen_addrs = xrecallocarray(
870 options->queued_listen_addrs,
871 options->num_queued_listens, options->num_queued_listens + 1,
872 sizeof(*options->queued_listen_addrs));
873 qla = &options->queued_listen_addrs[options->num_queued_listens++];
874 qla->addr = xstrdup(addr);
875 qla->port = port;
876 qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
880 * Process queued (text) ListenAddress entries.
882 static void
883 process_queued_listen_addrs(ServerOptions *options)
885 u_int i;
886 struct queued_listenaddr *qla;
888 if (options->num_ports == 0)
889 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
890 if (options->address_family == -1)
891 options->address_family = AF_UNSPEC;
893 for (i = 0; i < options->num_queued_listens; i++) {
894 qla = &options->queued_listen_addrs[i];
895 add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
896 free(qla->addr);
897 free(qla->rdomain);
899 free(options->queued_listen_addrs);
900 options->queued_listen_addrs = NULL;
901 options->num_queued_listens = 0;
905 * Inform channels layer of permitopen options for a single forwarding
906 * direction (local/remote).
908 static void
909 process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
910 char **opens, u_int num_opens)
912 u_int i;
913 int port;
914 char *host, *arg, *oarg;
915 int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
916 const char *what = lookup_opcode_name(opcode);
918 channel_clear_permission(ssh, FORWARD_ADM, where);
919 if (num_opens == 0)
920 return; /* permit any */
922 /* handle keywords: "any" / "none" */
923 if (num_opens == 1 && strcmp(opens[0], "any") == 0)
924 return;
925 if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
926 channel_disable_admin(ssh, where);
927 return;
929 /* Otherwise treat it as a list of permitted host:port */
930 for (i = 0; i < num_opens; i++) {
931 oarg = arg = xstrdup(opens[i]);
932 host = hpdelim(&arg);
933 if (host == NULL)
934 fatal_f("missing host in %s", what);
935 host = cleanhostname(host);
936 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
937 fatal_f("bad port number in %s", what);
938 /* Send it to channels layer */
939 channel_add_permission(ssh, FORWARD_ADM,
940 where, host, port);
941 free(oarg);
946 * Inform channels layer of permitopen options from configuration.
948 void
949 process_permitopen(struct ssh *ssh, ServerOptions *options)
951 process_permitopen_list(ssh, sPermitOpen,
952 options->permitted_opens, options->num_permitted_opens);
953 process_permitopen_list(ssh, sPermitListen,
954 options->permitted_listens,
955 options->num_permitted_listens);
958 struct connection_info *
959 get_connection_info(struct ssh *ssh, int populate, int use_dns)
961 static struct connection_info ci;
963 if (ssh == NULL || !populate)
964 return &ci;
965 ci.host = auth_get_canonical_hostname(ssh, use_dns);
966 ci.address = ssh_remote_ipaddr(ssh);
967 ci.laddress = ssh_local_ipaddr(ssh);
968 ci.lport = ssh_local_port(ssh);
969 ci.rdomain = ssh_packet_rdomain_in(ssh);
970 return &ci;
974 * The strategy for the Match blocks is that the config file is parsed twice.
976 * The first time is at startup. activep is initialized to 1 and the
977 * directives in the global context are processed and acted on. Hitting a
978 * Match directive unsets activep and the directives inside the block are
979 * checked for syntax only.
981 * The second time is after a connection has been established but before
982 * authentication. activep is initialized to 2 and global config directives
983 * are ignored since they have already been processed. If the criteria in a
984 * Match block is met, activep is set and the subsequent directives
985 * processed and actioned until EOF or another Match block unsets it. Any
986 * options set are copied into the main server config.
988 * Potential additions/improvements:
989 * - Add Match support for pre-kex directives, eg. Ciphers.
991 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
992 * Match Address 192.168.0.*
993 * Tag trusted
994 * Match Group wheel
995 * Tag trusted
996 * Match Tag trusted
997 * AllowTcpForwarding yes
998 * GatewayPorts clientspecified
999 * [...]
1001 * - Add a PermittedChannelRequests directive
1002 * Match Group shell
1003 * PermittedChannelRequests session,forwarded-tcpip
1006 static int
1007 match_cfg_line_group(const char *grps, int line, const char *user)
1009 int result = 0;
1010 struct passwd *pw;
1012 if (user == NULL)
1013 goto out;
1015 if ((pw = getpwnam(user)) == NULL) {
1016 debug("Can't match group at line %d because user %.100s does "
1017 "not exist", line, user);
1018 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
1019 debug("Can't Match group because user %.100s not in any group "
1020 "at line %d", user, line);
1021 } else if (ga_match_pattern_list(grps) != 1) {
1022 debug("user %.100s does not match group list %.100s at line %d",
1023 user, grps, line);
1024 } else {
1025 debug("user %.100s matched group list %.100s at line %d", user,
1026 grps, line);
1027 result = 1;
1029 out:
1030 ga_free();
1031 return result;
1034 static void
1035 match_test_missing_fatal(const char *criteria, const char *attrib)
1037 fatal("'Match %s' in configuration but '%s' not in connection "
1038 "test specification.", criteria, attrib);
1042 * All of the attributes on a single Match line are ANDed together, so we need
1043 * to check every attribute and set the result to zero if any attribute does
1044 * not match.
1046 static int
1047 match_cfg_line(char **condition, int line, struct connection_info *ci)
1049 int result = 1, attributes = 0, port;
1050 char *arg, *attrib, *cp = *condition;
1052 if (ci == NULL)
1053 debug3("checking syntax for 'Match %s'", cp);
1054 else
1055 debug3("checking match for '%s' user %s host %s addr %s "
1056 "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
1057 ci->host ? ci->host : "(null)",
1058 ci->address ? ci->address : "(null)",
1059 ci->laddress ? ci->laddress : "(null)", ci->lport);
1061 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
1062 /* Terminate on comment */
1063 if (*attrib == '#') {
1064 cp = NULL; /* mark all arguments consumed */
1065 break;
1067 arg = NULL;
1068 attributes++;
1069 /* Criterion "all" has no argument and must appear alone */
1070 if (strcasecmp(attrib, "all") == 0) {
1071 if (attributes > 1 || ((arg = strdelim(&cp)) != NULL &&
1072 *arg != '\0' && *arg != '#')) {
1073 error("'all' cannot be combined with other "
1074 "Match attributes");
1075 return -1;
1077 if (arg != NULL && *arg == '#')
1078 cp = NULL; /* mark all arguments consumed */
1079 *condition = cp;
1080 return 1;
1082 /* All other criteria require an argument */
1083 if ((arg = strdelim(&cp)) == NULL ||
1084 *arg == '\0' || *arg == '#') {
1085 error("Missing Match criteria for %s", attrib);
1086 return -1;
1088 if (strcasecmp(attrib, "user") == 0) {
1089 if (ci == NULL || (ci->test && ci->user == NULL)) {
1090 result = 0;
1091 continue;
1093 if (ci->user == NULL)
1094 match_test_missing_fatal("User", "user");
1095 if (match_usergroup_pattern_list(ci->user, arg) != 1)
1096 result = 0;
1097 else
1098 debug("user %.100s matched 'User %.100s' at "
1099 "line %d", ci->user, arg, line);
1100 } else if (strcasecmp(attrib, "group") == 0) {
1101 if (ci == NULL || (ci->test && ci->user == NULL)) {
1102 result = 0;
1103 continue;
1105 if (ci->user == NULL)
1106 match_test_missing_fatal("Group", "user");
1107 switch (match_cfg_line_group(arg, line, ci->user)) {
1108 case -1:
1109 return -1;
1110 case 0:
1111 result = 0;
1113 } else if (strcasecmp(attrib, "host") == 0) {
1114 if (ci == NULL || (ci->test && ci->host == NULL)) {
1115 result = 0;
1116 continue;
1118 if (ci->host == NULL)
1119 match_test_missing_fatal("Host", "host");
1120 if (match_hostname(ci->host, arg) != 1)
1121 result = 0;
1122 else
1123 debug("connection from %.100s matched 'Host "
1124 "%.100s' at line %d", ci->host, arg, line);
1125 } else if (strcasecmp(attrib, "address") == 0) {
1126 if (ci == NULL || (ci->test && ci->address == NULL)) {
1127 if (addr_match_list(NULL, arg) != 0)
1128 fatal("Invalid Match address argument "
1129 "'%s' at line %d", arg, line);
1130 result = 0;
1131 continue;
1133 if (ci->address == NULL)
1134 match_test_missing_fatal("Address", "addr");
1135 switch (addr_match_list(ci->address, arg)) {
1136 case 1:
1137 debug("connection from %.100s matched 'Address "
1138 "%.100s' at line %d", ci->address, arg, line);
1139 break;
1140 case 0:
1141 case -1:
1142 result = 0;
1143 break;
1144 case -2:
1145 return -1;
1147 } else if (strcasecmp(attrib, "localaddress") == 0){
1148 if (ci == NULL || (ci->test && ci->laddress == NULL)) {
1149 if (addr_match_list(NULL, arg) != 0)
1150 fatal("Invalid Match localaddress "
1151 "argument '%s' at line %d", arg,
1152 line);
1153 result = 0;
1154 continue;
1156 if (ci->laddress == NULL)
1157 match_test_missing_fatal("LocalAddress",
1158 "laddr");
1159 switch (addr_match_list(ci->laddress, arg)) {
1160 case 1:
1161 debug("connection from %.100s matched "
1162 "'LocalAddress %.100s' at line %d",
1163 ci->laddress, arg, line);
1164 break;
1165 case 0:
1166 case -1:
1167 result = 0;
1168 break;
1169 case -2:
1170 return -1;
1172 } else if (strcasecmp(attrib, "localport") == 0) {
1173 if ((port = a2port(arg)) == -1) {
1174 error("Invalid LocalPort '%s' on Match line",
1175 arg);
1176 return -1;
1178 if (ci == NULL || (ci->test && ci->lport == -1)) {
1179 result = 0;
1180 continue;
1182 if (ci->lport == 0)
1183 match_test_missing_fatal("LocalPort", "lport");
1184 /* TODO support port lists */
1185 if (port == ci->lport)
1186 debug("connection from %.100s matched "
1187 "'LocalPort %d' at line %d",
1188 ci->laddress, port, line);
1189 else
1190 result = 0;
1191 } else if (strcasecmp(attrib, "rdomain") == 0) {
1192 if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
1193 result = 0;
1194 continue;
1196 if (ci->rdomain == NULL)
1197 match_test_missing_fatal("RDomain", "rdomain");
1198 if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1199 result = 0;
1200 else
1201 debug("user %.100s matched 'RDomain %.100s' at "
1202 "line %d", ci->rdomain, arg, line);
1203 } else {
1204 error("Unsupported Match attribute %s", attrib);
1205 return -1;
1208 if (attributes == 0) {
1209 error("One or more attributes required for Match");
1210 return -1;
1212 if (ci != NULL)
1213 debug3("match %sfound", result ? "" : "not ");
1214 *condition = cp;
1215 return result;
1218 #define WHITESPACE " \t\r\n"
1220 /* Multistate option parsing */
1221 struct multistate {
1222 char *key;
1223 int value;
1225 static const struct multistate multistate_flag[] = {
1226 { "yes", 1 },
1227 { "no", 0 },
1228 { NULL, -1 }
1230 static const struct multistate multistate_ignore_rhosts[] = {
1231 { "yes", IGNORE_RHOSTS_YES },
1232 { "no", IGNORE_RHOSTS_NO },
1233 { "shosts-only", IGNORE_RHOSTS_SHOSTS },
1234 { NULL, -1 }
1236 static const struct multistate multistate_addressfamily[] = {
1237 { "inet", AF_INET },
1238 { "inet6", AF_INET6 },
1239 { "any", AF_UNSPEC },
1240 { NULL, -1 }
1242 static const struct multistate multistate_permitrootlogin[] = {
1243 { "without-password", PERMIT_NO_PASSWD },
1244 { "prohibit-password", PERMIT_NO_PASSWD },
1245 { "forced-commands-only", PERMIT_FORCED_ONLY },
1246 { "yes", PERMIT_YES },
1247 { "no", PERMIT_NO },
1248 { NULL, -1 }
1250 static const struct multistate multistate_compression[] = {
1251 #ifdef WITH_ZLIB
1252 { "yes", COMP_DELAYED },
1253 { "delayed", COMP_DELAYED },
1254 #endif
1255 { "no", COMP_NONE },
1256 { NULL, -1 }
1258 static const struct multistate multistate_gatewayports[] = {
1259 { "clientspecified", 2 },
1260 { "yes", 1 },
1261 { "no", 0 },
1262 { NULL, -1 }
1264 static const struct multistate multistate_tcpfwd[] = {
1265 { "yes", FORWARD_ALLOW },
1266 { "all", FORWARD_ALLOW },
1267 { "no", FORWARD_DENY },
1268 { "remote", FORWARD_REMOTE },
1269 { "local", FORWARD_LOCAL },
1270 { NULL, -1 }
1273 static int
1274 process_server_config_line_depth(ServerOptions *options, char *line,
1275 const char *filename, int linenum, int *activep,
1276 struct connection_info *connectinfo, int *inc_flags, int depth,
1277 struct include_list *includes)
1279 char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
1280 int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
1281 SyslogFacility *log_facility_ptr;
1282 LogLevel *log_level_ptr;
1283 ServerOpCodes opcode;
1284 u_int i, *uintptr, uvalue, flags = 0;
1285 size_t len;
1286 long long val64;
1287 const struct multistate *multistate_ptr;
1288 const char *errstr;
1289 struct include_item *item;
1290 glob_t gbuf;
1291 char **oav = NULL, **av;
1292 int oac = 0, ac;
1293 int ret = -1;
1295 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1296 if ((len = strlen(line)) == 0)
1297 return 0;
1298 for (len--; len > 0; len--) {
1299 if (strchr(WHITESPACE "\f", line[len]) == NULL)
1300 break;
1301 line[len] = '\0';
1304 str = line;
1305 if ((keyword = strdelim(&str)) == NULL)
1306 return 0;
1307 /* Ignore leading whitespace */
1308 if (*keyword == '\0')
1309 keyword = strdelim(&str);
1310 if (!keyword || !*keyword || *keyword == '#')
1311 return 0;
1312 if (str == NULL || *str == '\0') {
1313 error("%s line %d: no argument after keyword \"%s\"",
1314 filename, linenum, keyword);
1315 return -1;
1317 intptr = NULL;
1318 charptr = NULL;
1319 opcode = parse_token(keyword, filename, linenum, &flags);
1321 if (argv_split(str, &oac, &oav, 1) != 0) {
1322 error("%s line %d: invalid quotes", filename, linenum);
1323 return -1;
1325 ac = oac;
1326 av = oav;
1328 if (activep == NULL) { /* We are processing a command line directive */
1329 cmdline = 1;
1330 activep = &cmdline;
1332 if (*activep && opcode != sMatch && opcode != sInclude)
1333 debug3("%s:%d setting %s %s", filename, linenum, keyword, str);
1334 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1335 if (connectinfo == NULL) {
1336 fatal("%s line %d: Directive '%s' is not allowed "
1337 "within a Match block", filename, linenum, keyword);
1338 } else { /* this is a directive we have already processed */
1339 ret = 0;
1340 goto out;
1344 switch (opcode) {
1345 /* Portable-specific options */
1346 case sUsePAM:
1347 intptr = &options->use_pam;
1348 goto parse_flag;
1350 /* Standard Options */
1351 case sBadOption:
1352 goto out;
1353 case sPort:
1354 /* ignore ports from configfile if cmdline specifies ports */
1355 if (options->ports_from_cmdline) {
1356 argv_consume(&ac);
1357 break;
1359 if (options->num_ports >= MAX_PORTS)
1360 fatal("%s line %d: too many ports.",
1361 filename, linenum);
1362 arg = argv_next(&ac, &av);
1363 if (!arg || *arg == '\0')
1364 fatal("%s line %d: missing port number.",
1365 filename, linenum);
1366 options->ports[options->num_ports++] = a2port(arg);
1367 if (options->ports[options->num_ports-1] <= 0)
1368 fatal("%s line %d: Badly formatted port number.",
1369 filename, linenum);
1370 break;
1372 case sLoginGraceTime:
1373 intptr = &options->login_grace_time;
1374 parse_time:
1375 arg = argv_next(&ac, &av);
1376 if (!arg || *arg == '\0')
1377 fatal("%s line %d: missing time value.",
1378 filename, linenum);
1379 if ((value = convtime(arg)) == -1)
1380 fatal("%s line %d: invalid time value.",
1381 filename, linenum);
1382 if (*activep && *intptr == -1)
1383 *intptr = value;
1384 break;
1386 case sListenAddress:
1387 arg = argv_next(&ac, &av);
1388 if (arg == NULL || *arg == '\0')
1389 fatal("%s line %d: missing address",
1390 filename, linenum);
1391 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
1392 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1393 && strchr(p+1, ':') != NULL) {
1394 port = 0;
1395 p = arg;
1396 } else {
1397 arg2 = NULL;
1398 p = hpdelim(&arg);
1399 if (p == NULL)
1400 fatal("%s line %d: bad address:port usage",
1401 filename, linenum);
1402 p = cleanhostname(p);
1403 if (arg == NULL)
1404 port = 0;
1405 else if ((port = a2port(arg)) <= 0)
1406 fatal("%s line %d: bad port number",
1407 filename, linenum);
1409 /* Optional routing table */
1410 arg2 = NULL;
1411 if ((arg = argv_next(&ac, &av)) != NULL) {
1412 if (strcmp(arg, "rdomain") != 0 ||
1413 (arg2 = argv_next(&ac, &av)) == NULL)
1414 fatal("%s line %d: bad ListenAddress syntax",
1415 filename, linenum);
1416 if (!valid_rdomain(arg2))
1417 fatal("%s line %d: bad routing domain",
1418 filename, linenum);
1420 queue_listen_addr(options, p, arg2, port);
1422 break;
1424 case sAddressFamily:
1425 intptr = &options->address_family;
1426 multistate_ptr = multistate_addressfamily;
1427 parse_multistate:
1428 arg = argv_next(&ac, &av);
1429 if (!arg || *arg == '\0')
1430 fatal("%s line %d: missing argument.",
1431 filename, linenum);
1432 value = -1;
1433 for (i = 0; multistate_ptr[i].key != NULL; i++) {
1434 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1435 value = multistate_ptr[i].value;
1436 break;
1439 if (value == -1)
1440 fatal("%s line %d: unsupported option \"%s\".",
1441 filename, linenum, arg);
1442 if (*activep && *intptr == -1)
1443 *intptr = value;
1444 break;
1446 case sHostKeyFile:
1447 arg = argv_next(&ac, &av);
1448 if (!arg || *arg == '\0')
1449 fatal("%s line %d: missing file name.",
1450 filename, linenum);
1451 if (*activep) {
1452 servconf_add_hostkey(filename, linenum,
1453 options, arg, 1);
1455 break;
1457 case sHostKeyAgent:
1458 charptr = &options->host_key_agent;
1459 arg = argv_next(&ac, &av);
1460 if (!arg || *arg == '\0')
1461 fatal("%s line %d: missing socket name.",
1462 filename, linenum);
1463 if (*activep && *charptr == NULL)
1464 *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1465 xstrdup(arg) : derelativise_path(arg);
1466 break;
1468 case sHostCertificate:
1469 arg = argv_next(&ac, &av);
1470 if (!arg || *arg == '\0')
1471 fatal("%s line %d: missing file name.",
1472 filename, linenum);
1473 if (*activep)
1474 servconf_add_hostcert(filename, linenum, options, arg);
1475 break;
1477 case sPidFile:
1478 charptr = &options->pid_file;
1479 parse_filename:
1480 arg = argv_next(&ac, &av);
1481 if (!arg || *arg == '\0')
1482 fatal("%s line %d: missing file name.",
1483 filename, linenum);
1484 if (*activep && *charptr == NULL) {
1485 *charptr = derelativise_path(arg);
1486 /* increase optional counter */
1487 if (intptr != NULL)
1488 *intptr = *intptr + 1;
1490 break;
1492 case sModuliFile:
1493 charptr = &options->moduli_file;
1494 goto parse_filename;
1496 case sPermitRootLogin:
1497 intptr = &options->permit_root_login;
1498 multistate_ptr = multistate_permitrootlogin;
1499 goto parse_multistate;
1501 case sIgnoreRhosts:
1502 intptr = &options->ignore_rhosts;
1503 multistate_ptr = multistate_ignore_rhosts;
1504 goto parse_multistate;
1506 case sIgnoreUserKnownHosts:
1507 intptr = &options->ignore_user_known_hosts;
1508 parse_flag:
1509 multistate_ptr = multistate_flag;
1510 goto parse_multistate;
1512 case sHostbasedAuthentication:
1513 intptr = &options->hostbased_authentication;
1514 goto parse_flag;
1516 case sHostbasedUsesNameFromPacketOnly:
1517 intptr = &options->hostbased_uses_name_from_packet_only;
1518 goto parse_flag;
1520 case sHostbasedAcceptedAlgorithms:
1521 charptr = &options->hostbased_accepted_algos;
1522 parse_pubkey_algos:
1523 arg = argv_next(&ac, &av);
1524 if (!arg || *arg == '\0')
1525 fatal("%s line %d: Missing argument.",
1526 filename, linenum);
1527 if (*arg != '-' &&
1528 !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1529 arg + 1 : arg, 1))
1530 fatal("%s line %d: Bad key types '%s'.",
1531 filename, linenum, arg ? arg : "<NONE>");
1532 if (*activep && *charptr == NULL)
1533 *charptr = xstrdup(arg);
1534 break;
1536 case sHostKeyAlgorithms:
1537 charptr = &options->hostkeyalgorithms;
1538 goto parse_pubkey_algos;
1540 case sCASignatureAlgorithms:
1541 charptr = &options->ca_sign_algorithms;
1542 goto parse_pubkey_algos;
1544 case sPubkeyAuthentication:
1545 intptr = &options->pubkey_authentication;
1546 goto parse_flag;
1548 case sPubkeyAcceptedAlgorithms:
1549 charptr = &options->pubkey_accepted_algos;
1550 goto parse_pubkey_algos;
1552 case sPubkeyAuthOptions:
1553 intptr = &options->pubkey_auth_options;
1554 value = 0;
1555 while ((arg = argv_next(&ac, &av)) != NULL) {
1556 if (strcasecmp(arg, "none") == 0)
1557 continue;
1558 if (strcasecmp(arg, "touch-required") == 0)
1559 value |= PUBKEYAUTH_TOUCH_REQUIRED;
1560 else if (strcasecmp(arg, "verify-required") == 0)
1561 value |= PUBKEYAUTH_VERIFY_REQUIRED;
1562 else {
1563 error("%s line %d: unsupported %s option %s",
1564 filename, linenum, keyword, arg);
1565 goto out;
1568 if (*activep && *intptr == -1)
1569 *intptr = value;
1570 break;
1572 case sKerberosAuthentication:
1573 intptr = &options->kerberos_authentication;
1574 goto parse_flag;
1576 case sKerberosOrLocalPasswd:
1577 intptr = &options->kerberos_or_local_passwd;
1578 goto parse_flag;
1580 case sKerberosTicketCleanup:
1581 intptr = &options->kerberos_ticket_cleanup;
1582 goto parse_flag;
1584 case sKerberosGetAFSToken:
1585 intptr = &options->kerberos_get_afs_token;
1586 goto parse_flag;
1588 case sGssAuthentication:
1589 intptr = &options->gss_authentication;
1590 goto parse_flag;
1592 case sGssCleanupCreds:
1593 intptr = &options->gss_cleanup_creds;
1594 goto parse_flag;
1596 case sGssStrictAcceptor:
1597 intptr = &options->gss_strict_acceptor;
1598 goto parse_flag;
1600 case sPasswordAuthentication:
1601 intptr = &options->password_authentication;
1602 goto parse_flag;
1604 case sKbdInteractiveAuthentication:
1605 intptr = &options->kbd_interactive_authentication;
1606 goto parse_flag;
1608 case sPrintMotd:
1609 intptr = &options->print_motd;
1610 goto parse_flag;
1612 case sPrintLastLog:
1613 intptr = &options->print_lastlog;
1614 goto parse_flag;
1616 case sX11Forwarding:
1617 intptr = &options->x11_forwarding;
1618 goto parse_flag;
1620 case sX11DisplayOffset:
1621 intptr = &options->x11_display_offset;
1622 parse_int:
1623 arg = argv_next(&ac, &av);
1624 if ((errstr = atoi_err(arg, &value)) != NULL)
1625 fatal("%s line %d: %s integer value %s.",
1626 filename, linenum, keyword, errstr);
1627 if (*activep && *intptr == -1)
1628 *intptr = value;
1629 break;
1631 case sX11UseLocalhost:
1632 intptr = &options->x11_use_localhost;
1633 goto parse_flag;
1635 case sXAuthLocation:
1636 charptr = &options->xauth_location;
1637 goto parse_filename;
1639 case sPermitTTY:
1640 intptr = &options->permit_tty;
1641 goto parse_flag;
1643 case sPermitUserRC:
1644 intptr = &options->permit_user_rc;
1645 goto parse_flag;
1647 case sStrictModes:
1648 intptr = &options->strict_modes;
1649 goto parse_flag;
1651 case sTCPKeepAlive:
1652 intptr = &options->tcp_keep_alive;
1653 goto parse_flag;
1655 case sEmptyPasswd:
1656 intptr = &options->permit_empty_passwd;
1657 goto parse_flag;
1659 case sPermitUserEnvironment:
1660 intptr = &options->permit_user_env;
1661 charptr = &options->permit_user_env_allowlist;
1662 arg = argv_next(&ac, &av);
1663 if (!arg || *arg == '\0')
1664 fatal("%s line %d: %s missing argument.",
1665 filename, linenum, keyword);
1666 value = 0;
1667 p = NULL;
1668 if (strcmp(arg, "yes") == 0)
1669 value = 1;
1670 else if (strcmp(arg, "no") == 0)
1671 value = 0;
1672 else {
1673 /* Pattern-list specified */
1674 value = 1;
1675 p = xstrdup(arg);
1677 if (*activep && *intptr == -1) {
1678 *intptr = value;
1679 *charptr = p;
1680 p = NULL;
1682 free(p);
1683 break;
1685 case sCompression:
1686 intptr = &options->compression;
1687 multistate_ptr = multistate_compression;
1688 goto parse_multistate;
1690 case sRekeyLimit:
1691 arg = argv_next(&ac, &av);
1692 if (!arg || *arg == '\0')
1693 fatal("%s line %d: %s missing argument.",
1694 filename, linenum, keyword);
1695 if (strcmp(arg, "default") == 0) {
1696 val64 = 0;
1697 } else {
1698 if (scan_scaled(arg, &val64) == -1)
1699 fatal("%.200s line %d: Bad %s number '%s': %s",
1700 filename, linenum, keyword,
1701 arg, strerror(errno));
1702 if (val64 != 0 && val64 < 16)
1703 fatal("%.200s line %d: %s too small",
1704 filename, linenum, keyword);
1706 if (*activep && options->rekey_limit == -1)
1707 options->rekey_limit = val64;
1708 if (ac != 0) { /* optional rekey interval present */
1709 if (strcmp(av[0], "none") == 0) {
1710 (void)argv_next(&ac, &av); /* discard */
1711 break;
1713 intptr = &options->rekey_interval;
1714 goto parse_time;
1716 break;
1718 case sGatewayPorts:
1719 intptr = &options->fwd_opts.gateway_ports;
1720 multistate_ptr = multistate_gatewayports;
1721 goto parse_multistate;
1723 case sUseDNS:
1724 intptr = &options->use_dns;
1725 goto parse_flag;
1727 case sLogFacility:
1728 log_facility_ptr = &options->log_facility;
1729 arg = argv_next(&ac, &av);
1730 value = log_facility_number(arg);
1731 if (value == SYSLOG_FACILITY_NOT_SET)
1732 fatal("%.200s line %d: unsupported log facility '%s'",
1733 filename, linenum, arg ? arg : "<NONE>");
1734 if (*log_facility_ptr == -1)
1735 *log_facility_ptr = (SyslogFacility) value;
1736 break;
1738 case sLogLevel:
1739 log_level_ptr = &options->log_level;
1740 arg = argv_next(&ac, &av);
1741 value = log_level_number(arg);
1742 if (value == SYSLOG_LEVEL_NOT_SET)
1743 fatal("%.200s line %d: unsupported log level '%s'",
1744 filename, linenum, arg ? arg : "<NONE>");
1745 if (*activep && *log_level_ptr == -1)
1746 *log_level_ptr = (LogLevel) value;
1747 break;
1749 case sLogVerbose:
1750 found = options->num_log_verbose == 0;
1751 i = 0;
1752 while ((arg = argv_next(&ac, &av)) != NULL) {
1753 if (*arg == '\0') {
1754 error("%s line %d: keyword %s empty argument",
1755 filename, linenum, keyword);
1756 goto out;
1758 /* Allow "none" only in first position */
1759 if (strcasecmp(arg, "none") == 0) {
1760 if (i > 0 || ac > 0) {
1761 error("%s line %d: keyword %s \"none\" "
1762 "argument must appear alone.",
1763 filename, linenum, keyword);
1764 goto out;
1767 i++;
1768 if (!found || !*activep)
1769 continue;
1770 opt_array_append(filename, linenum, keyword,
1771 &options->log_verbose, &options->num_log_verbose,
1772 arg);
1774 break;
1776 case sAllowTcpForwarding:
1777 intptr = &options->allow_tcp_forwarding;
1778 multistate_ptr = multistate_tcpfwd;
1779 goto parse_multistate;
1781 case sAllowStreamLocalForwarding:
1782 intptr = &options->allow_streamlocal_forwarding;
1783 multistate_ptr = multistate_tcpfwd;
1784 goto parse_multistate;
1786 case sAllowAgentForwarding:
1787 intptr = &options->allow_agent_forwarding;
1788 goto parse_flag;
1790 case sDisableForwarding:
1791 intptr = &options->disable_forwarding;
1792 goto parse_flag;
1794 case sAllowUsers:
1795 chararrayptr = &options->allow_users;
1796 uintptr = &options->num_allow_users;
1797 parse_allowdenyusers:
1798 while ((arg = argv_next(&ac, &av)) != NULL) {
1799 if (*arg == '\0' ||
1800 match_user(NULL, NULL, NULL, arg) == -1)
1801 fatal("%s line %d: invalid %s pattern: \"%s\"",
1802 filename, linenum, keyword, arg);
1803 if (!*activep)
1804 continue;
1805 opt_array_append(filename, linenum, keyword,
1806 chararrayptr, uintptr, arg);
1808 break;
1810 case sDenyUsers:
1811 chararrayptr = &options->deny_users;
1812 uintptr = &options->num_deny_users;
1813 goto parse_allowdenyusers;
1815 case sAllowGroups:
1816 chararrayptr = &options->allow_groups;
1817 uintptr = &options->num_allow_groups;
1818 parse_allowdenygroups:
1819 while ((arg = argv_next(&ac, &av)) != NULL) {
1820 if (*arg == '\0')
1821 fatal("%s line %d: empty %s pattern",
1822 filename, linenum, keyword);
1823 if (!*activep)
1824 continue;
1825 opt_array_append(filename, linenum, keyword,
1826 chararrayptr, uintptr, arg);
1828 break;
1830 case sDenyGroups:
1831 chararrayptr = &options->deny_groups;
1832 uintptr = &options->num_deny_groups;
1833 goto parse_allowdenygroups;
1835 case sCiphers:
1836 arg = argv_next(&ac, &av);
1837 if (!arg || *arg == '\0')
1838 fatal("%s line %d: %s missing argument.",
1839 filename, linenum, keyword);
1840 if (*arg != '-' &&
1841 !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1842 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1843 filename, linenum, arg ? arg : "<NONE>");
1844 if (options->ciphers == NULL)
1845 options->ciphers = xstrdup(arg);
1846 break;
1848 case sMacs:
1849 arg = argv_next(&ac, &av);
1850 if (!arg || *arg == '\0')
1851 fatal("%s line %d: %s missing argument.",
1852 filename, linenum, keyword);
1853 if (*arg != '-' &&
1854 !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1855 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1856 filename, linenum, arg ? arg : "<NONE>");
1857 if (options->macs == NULL)
1858 options->macs = xstrdup(arg);
1859 break;
1861 case sKexAlgorithms:
1862 arg = argv_next(&ac, &av);
1863 if (!arg || *arg == '\0')
1864 fatal("%s line %d: %s missing argument.",
1865 filename, linenum, keyword);
1866 if (*arg != '-' &&
1867 !kex_names_valid(*arg == '+' || *arg == '^' ?
1868 arg + 1 : arg))
1869 fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1870 filename, linenum, arg ? arg : "<NONE>");
1871 if (options->kex_algorithms == NULL)
1872 options->kex_algorithms = xstrdup(arg);
1873 break;
1875 case sSubsystem:
1876 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1877 fatal("%s line %d: too many subsystems defined.",
1878 filename, linenum);
1880 arg = argv_next(&ac, &av);
1881 if (!arg || *arg == '\0')
1882 fatal("%s line %d: %s missing argument.",
1883 filename, linenum, keyword);
1884 if (!*activep) {
1885 arg = argv_next(&ac, &av);
1886 break;
1888 for (i = 0; i < options->num_subsystems; i++)
1889 if (strcmp(arg, options->subsystem_name[i]) == 0)
1890 fatal("%s line %d: Subsystem '%s' "
1891 "already defined.", filename, linenum, arg);
1892 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1893 arg = argv_next(&ac, &av);
1894 if (!arg || *arg == '\0')
1895 fatal("%s line %d: Missing subsystem command.",
1896 filename, linenum);
1897 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1899 /* Collect arguments (separate to executable) */
1900 p = xstrdup(arg);
1901 len = strlen(p) + 1;
1902 while ((arg = argv_next(&ac, &av)) != NULL) {
1903 len += 1 + strlen(arg);
1904 p = xreallocarray(p, 1, len);
1905 strlcat(p, " ", len);
1906 strlcat(p, arg, len);
1908 options->subsystem_args[options->num_subsystems] = p;
1909 options->num_subsystems++;
1910 break;
1912 case sMaxStartups:
1913 arg = argv_next(&ac, &av);
1914 if (!arg || *arg == '\0')
1915 fatal("%s line %d: %s missing argument.",
1916 filename, linenum, keyword);
1917 if ((n = sscanf(arg, "%d:%d:%d",
1918 &options->max_startups_begin,
1919 &options->max_startups_rate,
1920 &options->max_startups)) == 3) {
1921 if (options->max_startups_begin >
1922 options->max_startups ||
1923 options->max_startups_rate > 100 ||
1924 options->max_startups_rate < 1)
1925 fatal("%s line %d: Invalid %s spec.",
1926 filename, linenum, keyword);
1927 } else if (n != 1)
1928 fatal("%s line %d: Invalid %s spec.",
1929 filename, linenum, keyword);
1930 else
1931 options->max_startups = options->max_startups_begin;
1932 break;
1934 case sPerSourceNetBlockSize:
1935 arg = argv_next(&ac, &av);
1936 if (!arg || *arg == '\0')
1937 fatal("%s line %d: %s missing argument.",
1938 filename, linenum, keyword);
1939 switch (n = sscanf(arg, "%d:%d", &value, &value2)) {
1940 case 2:
1941 if (value2 < 0 || value2 > 128)
1942 n = -1;
1943 /* FALLTHROUGH */
1944 case 1:
1945 if (value < 0 || value > 32)
1946 n = -1;
1948 if (n != 1 && n != 2)
1949 fatal("%s line %d: Invalid %s spec.",
1950 filename, linenum, keyword);
1951 if (*activep) {
1952 options->per_source_masklen_ipv4 = value;
1953 options->per_source_masklen_ipv6 = value2;
1955 break;
1957 case sPerSourceMaxStartups:
1958 arg = argv_next(&ac, &av);
1959 if (!arg || *arg == '\0')
1960 fatal("%s line %d: %s missing argument.",
1961 filename, linenum, keyword);
1962 if (strcmp(arg, "none") == 0) { /* no limit */
1963 value = INT_MAX;
1964 } else {
1965 if ((errstr = atoi_err(arg, &value)) != NULL)
1966 fatal("%s line %d: %s integer value %s.",
1967 filename, linenum, keyword, errstr);
1969 if (*activep)
1970 options->per_source_max_startups = value;
1971 break;
1973 case sMaxAuthTries:
1974 intptr = &options->max_authtries;
1975 goto parse_int;
1977 case sMaxSessions:
1978 intptr = &options->max_sessions;
1979 goto parse_int;
1981 case sBanner:
1982 charptr = &options->banner;
1983 goto parse_filename;
1986 * These options can contain %X options expanded at
1987 * connect time, so that you can specify paths like:
1989 * AuthorizedKeysFile /etc/ssh_keys/%u
1991 case sAuthorizedKeysFile:
1992 uvalue = options->num_authkeys_files;
1993 while ((arg = argv_next(&ac, &av)) != NULL) {
1994 if (*arg == '\0') {
1995 error("%s line %d: keyword %s empty argument",
1996 filename, linenum, keyword);
1997 goto out;
1999 arg2 = tilde_expand_filename(arg, getuid());
2000 if (*activep && uvalue == 0) {
2001 opt_array_append(filename, linenum, keyword,
2002 &options->authorized_keys_files,
2003 &options->num_authkeys_files, arg2);
2005 free(arg2);
2007 break;
2009 case sAuthorizedPrincipalsFile:
2010 charptr = &options->authorized_principals_file;
2011 arg = argv_next(&ac, &av);
2012 if (!arg || *arg == '\0')
2013 fatal("%s line %d: %s missing argument.",
2014 filename, linenum, keyword);
2015 if (*activep && *charptr == NULL) {
2016 *charptr = tilde_expand_filename(arg, getuid());
2017 /* increase optional counter */
2018 if (intptr != NULL)
2019 *intptr = *intptr + 1;
2021 break;
2023 case sClientAliveInterval:
2024 intptr = &options->client_alive_interval;
2025 goto parse_time;
2027 case sClientAliveCountMax:
2028 intptr = &options->client_alive_count_max;
2029 goto parse_int;
2031 case sAcceptEnv:
2032 while ((arg = argv_next(&ac, &av)) != NULL) {
2033 if (*arg == '\0' || strchr(arg, '=') != NULL)
2034 fatal("%s line %d: Invalid environment name.",
2035 filename, linenum);
2036 if (!*activep)
2037 continue;
2038 opt_array_append(filename, linenum, keyword,
2039 &options->accept_env, &options->num_accept_env,
2040 arg);
2042 break;
2044 case sSetEnv:
2045 uvalue = options->num_setenv;
2046 while ((arg = argv_next(&ac, &av)) != NULL) {
2047 if (*arg == '\0' || strchr(arg, '=') == NULL)
2048 fatal("%s line %d: Invalid environment.",
2049 filename, linenum);
2050 if (!*activep || uvalue != 0)
2051 continue;
2052 if (lookup_setenv_in_list(arg, options->setenv,
2053 options->num_setenv) != NULL) {
2054 debug2("%s line %d: ignoring duplicate env "
2055 "name \"%.64s\"", filename, linenum, arg);
2056 continue;
2058 opt_array_append(filename, linenum, keyword,
2059 &options->setenv, &options->num_setenv, arg);
2061 break;
2063 case sPermitTunnel:
2064 intptr = &options->permit_tun;
2065 arg = argv_next(&ac, &av);
2066 if (!arg || *arg == '\0')
2067 fatal("%s line %d: %s missing argument.",
2068 filename, linenum, keyword);
2069 value = -1;
2070 for (i = 0; tunmode_desc[i].val != -1; i++)
2071 if (strcmp(tunmode_desc[i].text, arg) == 0) {
2072 value = tunmode_desc[i].val;
2073 break;
2075 if (value == -1)
2076 fatal("%s line %d: bad %s argument %s",
2077 filename, linenum, keyword, arg);
2078 if (*activep && *intptr == -1)
2079 *intptr = value;
2080 break;
2082 case sInclude:
2083 if (cmdline) {
2084 fatal("Include directive not supported as a "
2085 "command-line option");
2087 value = 0;
2088 while ((arg2 = argv_next(&ac, &av)) != NULL) {
2089 if (*arg2 == '\0') {
2090 error("%s line %d: keyword %s empty argument",
2091 filename, linenum, keyword);
2092 goto out;
2094 value++;
2095 found = 0;
2096 if (*arg2 != '/' && *arg2 != '~') {
2097 xasprintf(&arg, "%s/%s", SSHDIR, arg2);
2098 } else
2099 arg = xstrdup(arg2);
2102 * Don't let included files clobber the containing
2103 * file's Match state.
2105 oactive = *activep;
2107 /* consult cache of include files */
2108 TAILQ_FOREACH(item, includes, entry) {
2109 if (strcmp(item->selector, arg) != 0)
2110 continue;
2111 if (item->filename != NULL) {
2112 parse_server_config_depth(options,
2113 item->filename, item->contents,
2114 includes, connectinfo,
2115 (*inc_flags & SSHCFG_MATCH_ONLY
2116 ? SSHCFG_MATCH_ONLY : (oactive
2117 ? 0 : SSHCFG_NEVERMATCH)),
2118 activep, depth + 1);
2120 found = 1;
2121 *activep = oactive;
2123 if (found != 0) {
2124 free(arg);
2125 continue;
2128 /* requested glob was not in cache */
2129 debug2("%s line %d: new include %s",
2130 filename, linenum, arg);
2131 if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
2132 if (r != GLOB_NOMATCH) {
2133 fatal("%s line %d: include \"%s\" glob "
2134 "failed", filename, linenum, arg);
2137 * If no entry matched then record a
2138 * placeholder to skip later glob calls.
2140 debug2("%s line %d: no match for %s",
2141 filename, linenum, arg);
2142 item = xcalloc(1, sizeof(*item));
2143 item->selector = strdup(arg);
2144 TAILQ_INSERT_TAIL(includes,
2145 item, entry);
2147 if (gbuf.gl_pathc > INT_MAX)
2148 fatal_f("too many glob results");
2149 for (n = 0; n < (int)gbuf.gl_pathc; n++) {
2150 debug2("%s line %d: including %s",
2151 filename, linenum, gbuf.gl_pathv[n]);
2152 item = xcalloc(1, sizeof(*item));
2153 item->selector = strdup(arg);
2154 item->filename = strdup(gbuf.gl_pathv[n]);
2155 if ((item->contents = sshbuf_new()) == NULL)
2156 fatal_f("sshbuf_new failed");
2157 load_server_config(item->filename,
2158 item->contents);
2159 parse_server_config_depth(options,
2160 item->filename, item->contents,
2161 includes, connectinfo,
2162 (*inc_flags & SSHCFG_MATCH_ONLY
2163 ? SSHCFG_MATCH_ONLY : (oactive
2164 ? 0 : SSHCFG_NEVERMATCH)),
2165 activep, depth + 1);
2166 *activep = oactive;
2167 TAILQ_INSERT_TAIL(includes, item, entry);
2169 globfree(&gbuf);
2170 free(arg);
2172 if (value == 0) {
2173 fatal("%s line %d: %s missing filename argument",
2174 filename, linenum, keyword);
2176 break;
2178 case sMatch:
2179 if (cmdline)
2180 fatal("Match directive not supported as a command-line "
2181 "option");
2182 value = match_cfg_line(&str, linenum,
2183 (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
2184 if (value < 0)
2185 fatal("%s line %d: Bad Match condition", filename,
2186 linenum);
2187 *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
2189 * The MATCH_ONLY flag is applicable only until the first
2190 * match block.
2192 *inc_flags &= ~SSHCFG_MATCH_ONLY;
2194 * If match_cfg_line() didn't consume all its arguments then
2195 * arrange for the extra arguments check below to fail.
2197 if (str == NULL || *str == '\0')
2198 argv_consume(&ac);
2199 break;
2201 case sPermitListen:
2202 case sPermitOpen:
2203 if (opcode == sPermitListen) {
2204 uintptr = &options->num_permitted_listens;
2205 chararrayptr = &options->permitted_listens;
2206 } else {
2207 uintptr = &options->num_permitted_opens;
2208 chararrayptr = &options->permitted_opens;
2210 arg = argv_next(&ac, &av);
2211 if (!arg || *arg == '\0')
2212 fatal("%s line %d: %s missing argument.",
2213 filename, linenum, keyword);
2214 uvalue = *uintptr; /* modified later */
2215 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
2216 if (*activep && uvalue == 0) {
2217 *uintptr = 1;
2218 *chararrayptr = xcalloc(1,
2219 sizeof(**chararrayptr));
2220 (*chararrayptr)[0] = xstrdup(arg);
2222 break;
2224 for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) {
2225 if (opcode == sPermitListen &&
2226 strchr(arg, ':') == NULL) {
2228 * Allow bare port number for PermitListen
2229 * to indicate a wildcard listen host.
2231 xasprintf(&arg2, "*:%s", arg);
2232 } else {
2233 arg2 = xstrdup(arg);
2234 p = hpdelim(&arg);
2235 if (p == NULL) {
2236 fatal("%s line %d: %s missing host",
2237 filename, linenum, keyword);
2239 p = cleanhostname(p);
2241 if (arg == NULL ||
2242 ((port = permitopen_port(arg)) < 0)) {
2243 fatal("%s line %d: %s bad port number",
2244 filename, linenum, keyword);
2246 if (*activep && uvalue == 0) {
2247 opt_array_append(filename, linenum, keyword,
2248 chararrayptr, uintptr, arg2);
2250 free(arg2);
2252 break;
2254 case sForceCommand:
2255 if (str == NULL || *str == '\0')
2256 fatal("%s line %d: %s missing argument.",
2257 filename, linenum, keyword);
2258 len = strspn(str, WHITESPACE);
2259 if (*activep && options->adm_forced_command == NULL)
2260 options->adm_forced_command = xstrdup(str + len);
2261 argv_consume(&ac);
2262 break;
2264 case sChrootDirectory:
2265 charptr = &options->chroot_directory;
2267 arg = argv_next(&ac, &av);
2268 if (!arg || *arg == '\0')
2269 fatal("%s line %d: %s missing argument.",
2270 filename, linenum, keyword);
2271 if (*activep && *charptr == NULL)
2272 *charptr = xstrdup(arg);
2273 break;
2275 case sTrustedUserCAKeys:
2276 charptr = &options->trusted_user_ca_keys;
2277 goto parse_filename;
2279 case sRevokedKeys:
2280 charptr = &options->revoked_keys_file;
2281 goto parse_filename;
2283 case sSecurityKeyProvider:
2284 charptr = &options->sk_provider;
2285 arg = argv_next(&ac, &av);
2286 if (!arg || *arg == '\0')
2287 fatal("%s line %d: %s missing argument.",
2288 filename, linenum, keyword);
2289 if (*activep && *charptr == NULL) {
2290 *charptr = strcasecmp(arg, "internal") == 0 ?
2291 xstrdup(arg) : derelativise_path(arg);
2292 /* increase optional counter */
2293 if (intptr != NULL)
2294 *intptr = *intptr + 1;
2296 break;
2298 case sIPQoS:
2299 arg = argv_next(&ac, &av);
2300 if (!arg || *arg == '\0')
2301 fatal("%s line %d: %s missing argument.",
2302 filename, linenum, keyword);
2303 if ((value = parse_ipqos(arg)) == -1)
2304 fatal("%s line %d: Bad %s value: %s",
2305 filename, linenum, keyword, arg);
2306 arg = argv_next(&ac, &av);
2307 if (arg == NULL)
2308 value2 = value;
2309 else if ((value2 = parse_ipqos(arg)) == -1)
2310 fatal("%s line %d: Bad %s value: %s",
2311 filename, linenum, keyword, arg);
2312 if (*activep) {
2313 options->ip_qos_interactive = value;
2314 options->ip_qos_bulk = value2;
2316 break;
2318 case sVersionAddendum:
2319 if (str == NULL || *str == '\0')
2320 fatal("%s line %d: %s missing argument.",
2321 filename, linenum, keyword);
2322 len = strspn(str, WHITESPACE);
2323 if (strchr(str + len, '\r') != NULL) {
2324 fatal("%.200s line %d: Invalid %s argument",
2325 filename, linenum, keyword);
2327 if ((arg = strchr(line, '#')) != NULL) {
2328 *arg = '\0';
2329 rtrim(line);
2331 if (*activep && options->version_addendum == NULL) {
2332 if (strcasecmp(str + len, "none") == 0)
2333 options->version_addendum = xstrdup("");
2334 else
2335 options->version_addendum = xstrdup(str + len);
2337 argv_consume(&ac);
2338 break;
2340 case sAuthorizedKeysCommand:
2341 charptr = &options->authorized_keys_command;
2342 parse_command:
2343 len = strspn(str, WHITESPACE);
2344 if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
2345 fatal("%.200s line %d: %s must be an absolute path",
2346 filename, linenum, keyword);
2348 if (*activep && options->authorized_keys_command == NULL)
2349 *charptr = xstrdup(str + len);
2350 argv_consume(&ac);
2351 break;
2353 case sAuthorizedKeysCommandUser:
2354 charptr = &options->authorized_keys_command_user;
2355 parse_localuser:
2356 arg = argv_next(&ac, &av);
2357 if (!arg || *arg == '\0') {
2358 fatal("%s line %d: missing %s argument.",
2359 filename, linenum, keyword);
2361 if (*activep && *charptr == NULL)
2362 *charptr = xstrdup(arg);
2363 break;
2365 case sAuthorizedPrincipalsCommand:
2366 charptr = &options->authorized_principals_command;
2367 goto parse_command;
2369 case sAuthorizedPrincipalsCommandUser:
2370 charptr = &options->authorized_principals_command_user;
2371 goto parse_localuser;
2373 case sAuthenticationMethods:
2374 found = options->num_auth_methods == 0;
2375 value = 0; /* seen "any" pseudo-method */
2376 value2 = 0; /* successfully parsed any method */
2377 while ((arg = argv_next(&ac, &av)) != NULL) {
2378 if (strcmp(arg, "any") == 0) {
2379 if (options->num_auth_methods > 0) {
2380 fatal("%s line %d: \"any\" must "
2381 "appear alone in %s",
2382 filename, linenum, keyword);
2384 value = 1;
2385 } else if (value) {
2386 fatal("%s line %d: \"any\" must appear "
2387 "alone in %s", filename, linenum, keyword);
2388 } else if (auth2_methods_valid(arg, 0) != 0) {
2389 fatal("%s line %d: invalid %s method list.",
2390 filename, linenum, keyword);
2392 value2 = 1;
2393 if (!found || !*activep)
2394 continue;
2395 opt_array_append(filename, linenum, keyword,
2396 &options->auth_methods,
2397 &options->num_auth_methods, arg);
2399 if (value2 == 0) {
2400 fatal("%s line %d: no %s specified",
2401 filename, linenum, keyword);
2403 break;
2405 case sStreamLocalBindMask:
2406 arg = argv_next(&ac, &av);
2407 if (!arg || *arg == '\0')
2408 fatal("%s line %d: %s missing argument.",
2409 filename, linenum, keyword);
2410 /* Parse mode in octal format */
2411 value = strtol(arg, &p, 8);
2412 if (arg == p || value < 0 || value > 0777)
2413 fatal("%s line %d: Invalid %s.",
2414 filename, linenum, keyword);
2415 if (*activep)
2416 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2417 break;
2419 case sStreamLocalBindUnlink:
2420 intptr = &options->fwd_opts.streamlocal_bind_unlink;
2421 goto parse_flag;
2423 case sFingerprintHash:
2424 arg = argv_next(&ac, &av);
2425 if (!arg || *arg == '\0')
2426 fatal("%s line %d: %s missing argument.",
2427 filename, linenum, keyword);
2428 if ((value = ssh_digest_alg_by_name(arg)) == -1)
2429 fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
2430 filename, linenum, keyword, arg);
2431 if (*activep)
2432 options->fingerprint_hash = value;
2433 break;
2435 case sExposeAuthInfo:
2436 intptr = &options->expose_userauth_info;
2437 goto parse_flag;
2439 case sRDomain:
2440 #if !defined(__OpenBSD__) && !defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
2441 fatal("%s line %d: setting RDomain not supported on this "
2442 "platform.", filename, linenum);
2443 #endif
2444 charptr = &options->routing_domain;
2445 arg = argv_next(&ac, &av);
2446 if (!arg || *arg == '\0')
2447 fatal("%s line %d: %s missing argument.",
2448 filename, linenum, keyword);
2449 if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2450 !valid_rdomain(arg))
2451 fatal("%s line %d: invalid routing domain",
2452 filename, linenum);
2453 if (*activep && *charptr == NULL)
2454 *charptr = xstrdup(arg);
2455 break;
2457 case sRequiredRSASize:
2458 intptr = &options->required_rsa_size;
2459 goto parse_int;
2461 case sDeprecated:
2462 case sIgnore:
2463 case sUnsupported:
2464 do_log2(opcode == sIgnore ?
2465 SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2466 "%s line %d: %s option %s", filename, linenum,
2467 opcode == sUnsupported ? "Unsupported" : "Deprecated",
2468 keyword);
2469 argv_consume(&ac);
2470 break;
2472 default:
2473 fatal("%s line %d: Missing handler for opcode %s (%d)",
2474 filename, linenum, keyword, opcode);
2476 /* Check that there is no garbage at end of line. */
2477 if (ac > 0) {
2478 error("%.200s line %d: keyword %s extra arguments "
2479 "at end of line", filename, linenum, keyword);
2480 goto out;
2483 /* success */
2484 ret = 0;
2485 out:
2486 argv_free(oav, oac);
2487 return ret;
2491 process_server_config_line(ServerOptions *options, char *line,
2492 const char *filename, int linenum, int *activep,
2493 struct connection_info *connectinfo, struct include_list *includes)
2495 int inc_flags = 0;
2497 return process_server_config_line_depth(options, line, filename,
2498 linenum, activep, connectinfo, &inc_flags, 0, includes);
2502 /* Reads the server configuration file. */
2504 void
2505 load_server_config(const char *filename, struct sshbuf *conf)
2507 struct stat st;
2508 char *line = NULL, *cp;
2509 size_t linesize = 0;
2510 FILE *f;
2511 int r, lineno = 0;
2513 debug2_f("filename %s", filename);
2514 if ((f = fopen(filename, "r")) == NULL) {
2515 perror(filename);
2516 exit(1);
2518 sshbuf_reset(conf);
2519 /* grow buffer, so realloc is avoided for large config files */
2520 if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
2521 (r = sshbuf_allocate(conf, st.st_size)) != 0)
2522 fatal_fr(r, "allocate");
2523 while (getline(&line, &linesize, f) != -1) {
2524 lineno++;
2526 * Strip whitespace
2527 * NB - preserve newlines, they are needed to reproduce
2528 * line numbers later for error messages
2530 cp = line + strspn(line, " \t\r");
2531 if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2532 fatal_fr(r, "sshbuf_put");
2534 free(line);
2535 if ((r = sshbuf_put_u8(conf, 0)) != 0)
2536 fatal_fr(r, "sshbuf_put_u8");
2537 fclose(f);
2538 debug2_f("done config len = %zu", sshbuf_len(conf));
2541 void
2542 parse_server_match_config(ServerOptions *options,
2543 struct include_list *includes, struct connection_info *connectinfo)
2545 ServerOptions mo;
2547 initialize_server_options(&mo);
2548 parse_server_config(&mo, "reprocess config", cfg, includes,
2549 connectinfo, 0);
2550 copy_set_server_options(options, &mo, 0);
2553 int parse_server_match_testspec(struct connection_info *ci, char *spec)
2555 char *p;
2557 while ((p = strsep(&spec, ",")) && *p != '\0') {
2558 if (strncmp(p, "addr=", 5) == 0) {
2559 ci->address = xstrdup(p + 5);
2560 } else if (strncmp(p, "host=", 5) == 0) {
2561 ci->host = xstrdup(p + 5);
2562 } else if (strncmp(p, "user=", 5) == 0) {
2563 ci->user = xstrdup(p + 5);
2564 } else if (strncmp(p, "laddr=", 6) == 0) {
2565 ci->laddress = xstrdup(p + 6);
2566 } else if (strncmp(p, "rdomain=", 8) == 0) {
2567 ci->rdomain = xstrdup(p + 8);
2568 } else if (strncmp(p, "lport=", 6) == 0) {
2569 ci->lport = a2port(p + 6);
2570 if (ci->lport == -1) {
2571 fprintf(stderr, "Invalid port '%s' in test mode"
2572 " specification %s\n", p+6, p);
2573 return -1;
2575 } else {
2576 fprintf(stderr, "Invalid test mode specification %s\n",
2578 return -1;
2581 return 0;
2585 * Copy any supported values that are set.
2587 * If the preauth flag is set, we do not bother copying the string or
2588 * array values that are not used pre-authentication, because any that we
2589 * do use must be explicitly sent in mm_getpwnamallow().
2591 void
2592 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2594 #define M_CP_INTOPT(n) do {\
2595 if (src->n != -1) \
2596 dst->n = src->n; \
2597 } while (0)
2599 M_CP_INTOPT(password_authentication);
2600 M_CP_INTOPT(gss_authentication);
2601 M_CP_INTOPT(pubkey_authentication);
2602 M_CP_INTOPT(pubkey_auth_options);
2603 M_CP_INTOPT(kerberos_authentication);
2604 M_CP_INTOPT(hostbased_authentication);
2605 M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2606 M_CP_INTOPT(kbd_interactive_authentication);
2607 M_CP_INTOPT(permit_root_login);
2608 M_CP_INTOPT(permit_empty_passwd);
2609 M_CP_INTOPT(ignore_rhosts);
2611 M_CP_INTOPT(allow_tcp_forwarding);
2612 M_CP_INTOPT(allow_streamlocal_forwarding);
2613 M_CP_INTOPT(allow_agent_forwarding);
2614 M_CP_INTOPT(disable_forwarding);
2615 M_CP_INTOPT(expose_userauth_info);
2616 M_CP_INTOPT(permit_tun);
2617 M_CP_INTOPT(fwd_opts.gateway_ports);
2618 M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2619 M_CP_INTOPT(x11_display_offset);
2620 M_CP_INTOPT(x11_forwarding);
2621 M_CP_INTOPT(x11_use_localhost);
2622 M_CP_INTOPT(permit_tty);
2623 M_CP_INTOPT(permit_user_rc);
2624 M_CP_INTOPT(max_sessions);
2625 M_CP_INTOPT(max_authtries);
2626 M_CP_INTOPT(client_alive_count_max);
2627 M_CP_INTOPT(client_alive_interval);
2628 M_CP_INTOPT(ip_qos_interactive);
2629 M_CP_INTOPT(ip_qos_bulk);
2630 M_CP_INTOPT(rekey_limit);
2631 M_CP_INTOPT(rekey_interval);
2632 M_CP_INTOPT(log_level);
2633 M_CP_INTOPT(required_rsa_size);
2636 * The bind_mask is a mode_t that may be unsigned, so we can't use
2637 * M_CP_INTOPT - it does a signed comparison that causes compiler
2638 * warnings.
2640 if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2641 dst->fwd_opts.streamlocal_bind_mask =
2642 src->fwd_opts.streamlocal_bind_mask;
2645 /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2646 #define M_CP_STROPT(n) do {\
2647 if (src->n != NULL && dst->n != src->n) { \
2648 free(dst->n); \
2649 dst->n = src->n; \
2651 } while(0)
2652 #define M_CP_STRARRAYOPT(s, num_s) do {\
2653 u_int i; \
2654 if (src->num_s != 0) { \
2655 for (i = 0; i < dst->num_s; i++) \
2656 free(dst->s[i]); \
2657 free(dst->s); \
2658 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2659 for (i = 0; i < src->num_s; i++) \
2660 dst->s[i] = xstrdup(src->s[i]); \
2661 dst->num_s = src->num_s; \
2663 } while(0)
2665 /* See comment in servconf.h */
2666 COPY_MATCH_STRING_OPTS();
2668 /* Arguments that accept '+...' need to be expanded */
2669 assemble_algorithms(dst);
2672 * The only things that should be below this point are string options
2673 * which are only used after authentication.
2675 if (preauth)
2676 return;
2678 /* These options may be "none" to clear a global setting */
2679 M_CP_STROPT(adm_forced_command);
2680 if (option_clear_or_none(dst->adm_forced_command)) {
2681 free(dst->adm_forced_command);
2682 dst->adm_forced_command = NULL;
2684 M_CP_STROPT(chroot_directory);
2685 if (option_clear_or_none(dst->chroot_directory)) {
2686 free(dst->chroot_directory);
2687 dst->chroot_directory = NULL;
2691 #undef M_CP_INTOPT
2692 #undef M_CP_STROPT
2693 #undef M_CP_STRARRAYOPT
2695 #define SERVCONF_MAX_DEPTH 16
2696 static void
2697 parse_server_config_depth(ServerOptions *options, const char *filename,
2698 struct sshbuf *conf, struct include_list *includes,
2699 struct connection_info *connectinfo, int flags, int *activep, int depth)
2701 int linenum, bad_options = 0;
2702 char *cp, *obuf, *cbuf;
2704 if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
2705 fatal("Too many recursive configuration includes");
2707 debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
2708 (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
2710 if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2711 fatal_f("sshbuf_dup_string failed");
2712 linenum = 1;
2713 while ((cp = strsep(&cbuf, "\n")) != NULL) {
2714 if (process_server_config_line_depth(options, cp,
2715 filename, linenum++, activep, connectinfo, &flags,
2716 depth, includes) != 0)
2717 bad_options++;
2719 free(obuf);
2720 if (bad_options > 0)
2721 fatal("%s: terminating, %d bad configuration options",
2722 filename, bad_options);
2725 void
2726 parse_server_config(ServerOptions *options, const char *filename,
2727 struct sshbuf *conf, struct include_list *includes,
2728 struct connection_info *connectinfo, int reexec)
2730 int active = connectinfo ? 0 : 1;
2731 parse_server_config_depth(options, filename, conf, includes,
2732 connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
2733 if (!reexec)
2734 process_queued_listen_addrs(options);
2737 static const char *
2738 fmt_multistate_int(int val, const struct multistate *m)
2740 u_int i;
2742 for (i = 0; m[i].key != NULL; i++) {
2743 if (m[i].value == val)
2744 return m[i].key;
2746 return "UNKNOWN";
2749 static const char *
2750 fmt_intarg(ServerOpCodes code, int val)
2752 if (val == -1)
2753 return "unset";
2754 switch (code) {
2755 case sAddressFamily:
2756 return fmt_multistate_int(val, multistate_addressfamily);
2757 case sPermitRootLogin:
2758 return fmt_multistate_int(val, multistate_permitrootlogin);
2759 case sGatewayPorts:
2760 return fmt_multistate_int(val, multistate_gatewayports);
2761 case sCompression:
2762 return fmt_multistate_int(val, multistate_compression);
2763 case sAllowTcpForwarding:
2764 return fmt_multistate_int(val, multistate_tcpfwd);
2765 case sAllowStreamLocalForwarding:
2766 return fmt_multistate_int(val, multistate_tcpfwd);
2767 case sIgnoreRhosts:
2768 return fmt_multistate_int(val, multistate_ignore_rhosts);
2769 case sFingerprintHash:
2770 return ssh_digest_alg_name(val);
2771 default:
2772 switch (val) {
2773 case 0:
2774 return "no";
2775 case 1:
2776 return "yes";
2777 default:
2778 return "UNKNOWN";
2783 static void
2784 dump_cfg_int(ServerOpCodes code, int val)
2786 printf("%s %d\n", lookup_opcode_name(code), val);
2789 static void
2790 dump_cfg_oct(ServerOpCodes code, int val)
2792 printf("%s 0%o\n", lookup_opcode_name(code), val);
2795 static void
2796 dump_cfg_fmtint(ServerOpCodes code, int val)
2798 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2801 static void
2802 dump_cfg_string(ServerOpCodes code, const char *val)
2804 printf("%s %s\n", lookup_opcode_name(code),
2805 val == NULL ? "none" : val);
2808 static void
2809 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2811 u_int i;
2813 for (i = 0; i < count; i++)
2814 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2817 static void
2818 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2820 u_int i;
2822 if (count <= 0 && code != sAuthenticationMethods)
2823 return;
2824 printf("%s", lookup_opcode_name(code));
2825 for (i = 0; i < count; i++)
2826 printf(" %s", vals[i]);
2827 if (code == sAuthenticationMethods && count == 0)
2828 printf(" any");
2829 printf("\n");
2832 static char *
2833 format_listen_addrs(struct listenaddr *la)
2835 int r;
2836 struct addrinfo *ai;
2837 char addr[NI_MAXHOST], port[NI_MAXSERV];
2838 char *laddr1 = xstrdup(""), *laddr2 = NULL;
2841 * ListenAddress must be after Port. add_one_listen_addr pushes
2842 * addresses onto a stack, so to maintain ordering we need to
2843 * print these in reverse order.
2845 for (ai = la->addrs; ai; ai = ai->ai_next) {
2846 if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2847 sizeof(addr), port, sizeof(port),
2848 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2849 error("getnameinfo: %.100s", ssh_gai_strerror(r));
2850 continue;
2852 laddr2 = laddr1;
2853 if (ai->ai_family == AF_INET6) {
2854 xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2855 addr, port,
2856 la->rdomain == NULL ? "" : " rdomain ",
2857 la->rdomain == NULL ? "" : la->rdomain,
2858 laddr2);
2859 } else {
2860 xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2861 addr, port,
2862 la->rdomain == NULL ? "" : " rdomain ",
2863 la->rdomain == NULL ? "" : la->rdomain,
2864 laddr2);
2866 free(laddr2);
2868 return laddr1;
2871 void
2872 dump_config(ServerOptions *o)
2874 char *s;
2875 u_int i;
2877 /* these are usually at the top of the config */
2878 for (i = 0; i < o->num_ports; i++)
2879 printf("port %d\n", o->ports[i]);
2880 dump_cfg_fmtint(sAddressFamily, o->address_family);
2882 for (i = 0; i < o->num_listen_addrs; i++) {
2883 s = format_listen_addrs(&o->listen_addrs[i]);
2884 printf("%s", s);
2885 free(s);
2888 /* integer arguments */
2889 #ifdef USE_PAM
2890 dump_cfg_fmtint(sUsePAM, o->use_pam);
2891 #endif
2892 dump_cfg_int(sLoginGraceTime, o->login_grace_time);
2893 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
2894 dump_cfg_int(sMaxAuthTries, o->max_authtries);
2895 dump_cfg_int(sMaxSessions, o->max_sessions);
2896 dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
2897 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
2898 dump_cfg_int(sRequiredRSASize, o->required_rsa_size);
2899 dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
2901 /* formatted integer arguments */
2902 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
2903 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
2904 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
2905 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
2906 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
2907 o->hostbased_uses_name_from_packet_only);
2908 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
2909 #ifdef KRB5
2910 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
2911 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
2912 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
2913 # ifdef USE_AFS
2914 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2915 # endif
2916 #endif
2917 #ifdef GSSAPI
2918 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
2919 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
2920 #endif
2921 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2922 dump_cfg_fmtint(sKbdInteractiveAuthentication,
2923 o->kbd_interactive_authentication);
2924 dump_cfg_fmtint(sPrintMotd, o->print_motd);
2925 #ifndef DISABLE_LASTLOG
2926 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
2927 #endif
2928 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
2929 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2930 dump_cfg_fmtint(sPermitTTY, o->permit_tty);
2931 dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
2932 dump_cfg_fmtint(sStrictModes, o->strict_modes);
2933 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
2934 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
2935 dump_cfg_fmtint(sCompression, o->compression);
2936 dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
2937 dump_cfg_fmtint(sUseDNS, o->use_dns);
2938 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2939 dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
2940 dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
2941 dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2942 dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2943 dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2944 dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
2946 /* string arguments */
2947 dump_cfg_string(sPidFile, o->pid_file);
2948 dump_cfg_string(sModuliFile, o->moduli_file);
2949 dump_cfg_string(sXAuthLocation, o->xauth_location);
2950 dump_cfg_string(sCiphers, o->ciphers);
2951 dump_cfg_string(sMacs, o->macs);
2952 dump_cfg_string(sBanner, o->banner);
2953 dump_cfg_string(sForceCommand, o->adm_forced_command);
2954 dump_cfg_string(sChrootDirectory, o->chroot_directory);
2955 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
2956 dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
2957 dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
2958 dump_cfg_string(sAuthorizedPrincipalsFile,
2959 o->authorized_principals_file);
2960 dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
2961 ? "none" : o->version_addendum);
2962 dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
2963 dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
2964 dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
2965 dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
2966 dump_cfg_string(sHostKeyAgent, o->host_key_agent);
2967 dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
2968 dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
2969 dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
2970 dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
2971 dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
2972 #if defined(__OpenBSD__) || defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
2973 dump_cfg_string(sRDomain, o->routing_domain);
2974 #endif
2976 /* string arguments requiring a lookup */
2977 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2978 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
2980 /* string array arguments */
2981 dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
2982 o->authorized_keys_files);
2983 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
2984 o->host_key_files);
2985 dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
2986 o->host_cert_files);
2987 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
2988 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
2989 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
2990 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
2991 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
2992 dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
2993 dump_cfg_strarray_oneline(sAuthenticationMethods,
2994 o->num_auth_methods, o->auth_methods);
2995 dump_cfg_strarray_oneline(sLogVerbose,
2996 o->num_log_verbose, o->log_verbose);
2998 /* other arguments */
2999 for (i = 0; i < o->num_subsystems; i++)
3000 printf("subsystem %s %s\n", o->subsystem_name[i],
3001 o->subsystem_args[i]);
3003 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
3004 o->max_startups_rate, o->max_startups);
3005 printf("persourcemaxstartups ");
3006 if (o->per_source_max_startups == INT_MAX)
3007 printf("none\n");
3008 else
3009 printf("%d\n", o->per_source_max_startups);
3010 printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4,
3011 o->per_source_masklen_ipv6);
3013 s = NULL;
3014 for (i = 0; tunmode_desc[i].val != -1; i++) {
3015 if (tunmode_desc[i].val == o->permit_tun) {
3016 s = tunmode_desc[i].text;
3017 break;
3020 dump_cfg_string(sPermitTunnel, s);
3022 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
3023 printf("%s\n", iptos2str(o->ip_qos_bulk));
3025 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
3026 o->rekey_interval);
3028 printf("permitopen");
3029 if (o->num_permitted_opens == 0)
3030 printf(" any");
3031 else {
3032 for (i = 0; i < o->num_permitted_opens; i++)
3033 printf(" %s", o->permitted_opens[i]);
3035 printf("\n");
3036 printf("permitlisten");
3037 if (o->num_permitted_listens == 0)
3038 printf(" any");
3039 else {
3040 for (i = 0; i < o->num_permitted_listens; i++)
3041 printf(" %s", o->permitted_listens[i]);
3043 printf("\n");
3045 if (o->permit_user_env_allowlist == NULL) {
3046 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
3047 } else {
3048 printf("permituserenvironment %s\n",
3049 o->permit_user_env_allowlist);
3052 printf("pubkeyauthoptions");
3053 if (o->pubkey_auth_options == 0)
3054 printf(" none");
3055 if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
3056 printf(" touch-required");
3057 if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
3058 printf(" verify-required");
3059 printf("\n");