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