Disable security key for bigendian interop.
[openssh.git] / servconf.c
blob2abf2846a2c7132be0d3155c3367964e313f1f3b
1 /* $OpenBSD: servconf.c,v 1.419 2024/09/25 01:24:04 djm Exp $ */
2 /*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
13 #include "includes.h"
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <sys/stat.h>
18 #ifdef __OpenBSD__
19 #include <sys/sysctl.h>
20 #endif
22 #include <netinet/in.h>
23 #include <netinet/in_systm.h>
24 #include <netinet/ip.h>
25 #ifdef HAVE_NET_ROUTE_H
26 #include <net/route.h>
27 #endif
29 #include <ctype.h>
30 #include <netdb.h>
31 #include <pwd.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <signal.h>
36 #include <unistd.h>
37 #include <limits.h>
38 #include <stdarg.h>
39 #include <errno.h>
40 #ifdef HAVE_UTIL_H
41 #include <util.h>
42 #endif
43 #ifdef USE_SYSTEM_GLOB
44 # include <glob.h>
45 #else
46 # include "openbsd-compat/glob.h"
47 #endif
49 #include "openbsd-compat/sys-queue.h"
50 #include "xmalloc.h"
51 #include "ssh.h"
52 #include "log.h"
53 #include "sshbuf.h"
54 #include "misc.h"
55 #include "servconf.h"
56 #include "pathnames.h"
57 #include "cipher.h"
58 #include "sshkey.h"
59 #include "kex.h"
60 #include "mac.h"
61 #include "match.h"
62 #include "channels.h"
63 #include "groupaccess.h"
64 #include "canohost.h"
65 #include "packet.h"
66 #include "ssherr.h"
67 #include "hostfile.h"
68 #include "auth.h"
69 #include "myproposal.h"
70 #include "digest.h"
72 #if !defined(SSHD_PAM_SERVICE)
73 # define SSHD_PAM_SERVICE "sshd"
74 #endif
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);
84 extern struct sshbuf *cfg;
86 /* Initializes the server options to their default values. */
88 void
89 initialize_server_options(ServerOptions *options)
91 memset(options, 0, sizeof(*options));
93 /* Portable-specific options */
94 options->use_pam = -1;
95 options->pam_service_name = NULL;
97 /* Standard Options */
98 options->num_ports = 0;
99 options->ports_from_cmdline = 0;
100 options->queued_listen_addrs = NULL;
101 options->num_queued_listens = 0;
102 options->listen_addrs = NULL;
103 options->num_listen_addrs = 0;
104 options->address_family = -1;
105 options->routing_domain = NULL;
106 options->num_host_key_files = 0;
107 options->num_host_cert_files = 0;
108 options->host_key_agent = NULL;
109 options->pid_file = NULL;
110 options->login_grace_time = -1;
111 options->permit_root_login = PERMIT_NOT_SET;
112 options->ignore_rhosts = -1;
113 options->ignore_user_known_hosts = -1;
114 options->print_motd = -1;
115 options->print_lastlog = -1;
116 options->x11_forwarding = -1;
117 options->x11_display_offset = -1;
118 options->x11_use_localhost = -1;
119 options->permit_tty = -1;
120 options->permit_user_rc = -1;
121 options->xauth_location = NULL;
122 options->strict_modes = -1;
123 options->tcp_keep_alive = -1;
124 options->log_facility = SYSLOG_FACILITY_NOT_SET;
125 options->log_level = SYSLOG_LEVEL_NOT_SET;
126 options->num_log_verbose = 0;
127 options->log_verbose = NULL;
128 options->hostbased_authentication = -1;
129 options->hostbased_uses_name_from_packet_only = -1;
130 options->hostbased_accepted_algos = NULL;
131 options->hostkeyalgorithms = NULL;
132 options->pubkey_authentication = -1;
133 options->pubkey_auth_options = -1;
134 options->pubkey_accepted_algos = NULL;
135 options->kerberos_authentication = -1;
136 options->kerberos_or_local_passwd = -1;
137 options->kerberos_ticket_cleanup = -1;
138 options->kerberos_get_afs_token = -1;
139 options->gss_authentication=-1;
140 options->gss_cleanup_creds = -1;
141 options->gss_strict_acceptor = -1;
142 options->password_authentication = -1;
143 options->kbd_interactive_authentication = -1;
144 options->permit_empty_passwd = -1;
145 options->permit_user_env = -1;
146 options->permit_user_env_allowlist = NULL;
147 options->compression = -1;
148 options->rekey_limit = -1;
149 options->rekey_interval = -1;
150 options->allow_tcp_forwarding = -1;
151 options->allow_streamlocal_forwarding = -1;
152 options->allow_agent_forwarding = -1;
153 options->num_allow_users = 0;
154 options->num_deny_users = 0;
155 options->num_allow_groups = 0;
156 options->num_deny_groups = 0;
157 options->ciphers = NULL;
158 options->macs = NULL;
159 options->kex_algorithms = NULL;
160 options->ca_sign_algorithms = NULL;
161 options->fwd_opts.gateway_ports = -1;
162 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
163 options->fwd_opts.streamlocal_bind_unlink = -1;
164 options->num_subsystems = 0;
165 options->max_startups_begin = -1;
166 options->max_startups_rate = -1;
167 options->max_startups = -1;
168 options->per_source_max_startups = -1;
169 options->per_source_masklen_ipv4 = -1;
170 options->per_source_masklen_ipv6 = -1;
171 options->per_source_penalty_exempt = NULL;
172 options->per_source_penalty.enabled = -1;
173 options->per_source_penalty.max_sources4 = -1;
174 options->per_source_penalty.max_sources6 = -1;
175 options->per_source_penalty.overflow_mode = -1;
176 options->per_source_penalty.overflow_mode6 = -1;
177 options->per_source_penalty.penalty_crash = -1;
178 options->per_source_penalty.penalty_authfail = -1;
179 options->per_source_penalty.penalty_noauth = -1;
180 options->per_source_penalty.penalty_grace = -1;
181 options->per_source_penalty.penalty_refuseconnection = -1;
182 options->per_source_penalty.penalty_max = -1;
183 options->per_source_penalty.penalty_min = -1;
184 options->max_authtries = -1;
185 options->max_sessions = -1;
186 options->banner = NULL;
187 options->use_dns = -1;
188 options->client_alive_interval = -1;
189 options->client_alive_count_max = -1;
190 options->num_authkeys_files = 0;
191 options->num_accept_env = 0;
192 options->num_setenv = 0;
193 options->permit_tun = -1;
194 options->permitted_opens = NULL;
195 options->permitted_listens = NULL;
196 options->adm_forced_command = NULL;
197 options->chroot_directory = NULL;
198 options->authorized_keys_command = NULL;
199 options->authorized_keys_command_user = NULL;
200 options->revoked_keys_file = NULL;
201 options->sk_provider = NULL;
202 options->trusted_user_ca_keys = NULL;
203 options->authorized_principals_file = NULL;
204 options->authorized_principals_command = NULL;
205 options->authorized_principals_command_user = NULL;
206 options->ip_qos_interactive = -1;
207 options->ip_qos_bulk = -1;
208 options->version_addendum = NULL;
209 options->fingerprint_hash = -1;
210 options->disable_forwarding = -1;
211 options->expose_userauth_info = -1;
212 options->required_rsa_size = -1;
213 options->channel_timeouts = NULL;
214 options->num_channel_timeouts = 0;
215 options->unused_connection_timeout = -1;
216 options->sshd_session_path = NULL;
217 options->sshd_auth_path = NULL;
218 options->refuse_connection = -1;
221 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
222 static int
223 option_clear_or_none(const char *o)
225 return o == NULL || strcasecmp(o, "none") == 0;
228 static void
229 assemble_algorithms(ServerOptions *o)
231 char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
232 char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
233 int r;
235 all_cipher = cipher_alg_list(',', 0);
236 all_mac = mac_alg_list(',');
237 all_kex = kex_alg_list(',');
238 all_key = sshkey_alg_list(0, 0, 1, ',');
239 all_sig = sshkey_alg_list(0, 1, 1, ',');
240 /* remove unsupported algos from default lists */
241 def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
242 def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
243 def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
244 def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
245 def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
246 #define ASSEMBLE(what, defaults, all) \
247 do { \
248 if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
249 fatal_fr(r, "%s", #what); \
250 } while (0)
251 ASSEMBLE(ciphers, def_cipher, all_cipher);
252 ASSEMBLE(macs, def_mac, all_mac);
253 ASSEMBLE(kex_algorithms, def_kex, all_kex);
254 ASSEMBLE(hostkeyalgorithms, def_key, all_key);
255 ASSEMBLE(hostbased_accepted_algos, def_key, all_key);
256 ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
257 ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
258 #undef ASSEMBLE
259 free(all_cipher);
260 free(all_mac);
261 free(all_kex);
262 free(all_key);
263 free(all_sig);
264 free(def_cipher);
265 free(def_mac);
266 free(def_kex);
267 free(def_key);
268 free(def_sig);
271 void
272 servconf_add_hostkey(const char *file, const int line,
273 ServerOptions *options, const char *path, int userprovided)
275 char *apath = derelativise_path(path);
277 opt_array_append2(file, line, "HostKey",
278 &options->host_key_files, &options->host_key_file_userprovided,
279 &options->num_host_key_files, apath, userprovided);
280 free(apath);
283 void
284 servconf_add_hostcert(const char *file, const int line,
285 ServerOptions *options, const char *path)
287 char *apath = derelativise_path(path);
289 opt_array_append(file, line, "HostCertificate",
290 &options->host_cert_files, &options->num_host_cert_files, apath);
291 free(apath);
294 void
295 fill_default_server_options(ServerOptions *options)
297 u_int i;
299 /* Portable-specific options */
300 if (options->use_pam == -1)
301 options->use_pam = 0;
302 if (options->pam_service_name == NULL)
303 options->pam_service_name = xstrdup(SSHD_PAM_SERVICE);
305 /* Standard Options */
306 if (options->num_host_key_files == 0) {
307 /* fill default hostkeys for protocols */
308 servconf_add_hostkey("[default]", 0, options,
309 _PATH_HOST_RSA_KEY_FILE, 0);
310 #ifdef OPENSSL_HAS_ECC
311 servconf_add_hostkey("[default]", 0, options,
312 _PATH_HOST_ECDSA_KEY_FILE, 0);
313 #endif
314 servconf_add_hostkey("[default]", 0, options,
315 _PATH_HOST_ED25519_KEY_FILE, 0);
316 #ifdef WITH_XMSS
317 servconf_add_hostkey("[default]", 0, options,
318 _PATH_HOST_XMSS_KEY_FILE, 0);
319 #endif /* WITH_XMSS */
321 /* No certificates by default */
322 if (options->num_ports == 0)
323 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
324 if (options->address_family == -1)
325 options->address_family = AF_UNSPEC;
326 if (options->listen_addrs == NULL)
327 add_listen_addr(options, NULL, NULL, 0);
328 if (options->pid_file == NULL)
329 options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
330 if (options->moduli_file == NULL)
331 options->moduli_file = xstrdup(_PATH_DH_MODULI);
332 if (options->login_grace_time == -1)
333 options->login_grace_time = 120;
334 if (options->permit_root_login == PERMIT_NOT_SET)
335 options->permit_root_login = PERMIT_NO_PASSWD;
336 if (options->ignore_rhosts == -1)
337 options->ignore_rhosts = 1;
338 if (options->ignore_user_known_hosts == -1)
339 options->ignore_user_known_hosts = 0;
340 if (options->print_motd == -1)
341 options->print_motd = 1;
342 if (options->print_lastlog == -1)
343 options->print_lastlog = 1;
344 if (options->x11_forwarding == -1)
345 options->x11_forwarding = 0;
346 if (options->x11_display_offset == -1)
347 options->x11_display_offset = 10;
348 if (options->x11_use_localhost == -1)
349 options->x11_use_localhost = 1;
350 if (options->xauth_location == NULL)
351 options->xauth_location = xstrdup(_PATH_XAUTH);
352 if (options->permit_tty == -1)
353 options->permit_tty = 1;
354 if (options->permit_user_rc == -1)
355 options->permit_user_rc = 1;
356 if (options->strict_modes == -1)
357 options->strict_modes = 1;
358 if (options->tcp_keep_alive == -1)
359 options->tcp_keep_alive = 1;
360 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
361 options->log_facility = SYSLOG_FACILITY_AUTH;
362 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
363 options->log_level = SYSLOG_LEVEL_INFO;
364 if (options->hostbased_authentication == -1)
365 options->hostbased_authentication = 0;
366 if (options->hostbased_uses_name_from_packet_only == -1)
367 options->hostbased_uses_name_from_packet_only = 0;
368 if (options->pubkey_authentication == -1)
369 options->pubkey_authentication = 1;
370 if (options->pubkey_auth_options == -1)
371 options->pubkey_auth_options = 0;
372 if (options->kerberos_authentication == -1)
373 options->kerberos_authentication = 0;
374 if (options->kerberos_or_local_passwd == -1)
375 options->kerberos_or_local_passwd = 1;
376 if (options->kerberos_ticket_cleanup == -1)
377 options->kerberos_ticket_cleanup = 1;
378 if (options->kerberos_get_afs_token == -1)
379 options->kerberos_get_afs_token = 0;
380 if (options->gss_authentication == -1)
381 options->gss_authentication = 0;
382 if (options->gss_cleanup_creds == -1)
383 options->gss_cleanup_creds = 1;
384 if (options->gss_strict_acceptor == -1)
385 options->gss_strict_acceptor = 1;
386 if (options->password_authentication == -1)
387 options->password_authentication = 1;
388 if (options->kbd_interactive_authentication == -1)
389 options->kbd_interactive_authentication = 1;
390 if (options->permit_empty_passwd == -1)
391 options->permit_empty_passwd = 0;
392 if (options->permit_user_env == -1) {
393 options->permit_user_env = 0;
394 options->permit_user_env_allowlist = NULL;
396 if (options->compression == -1)
397 #ifdef WITH_ZLIB
398 options->compression = COMP_DELAYED;
399 #else
400 options->compression = COMP_NONE;
401 #endif
403 if (options->rekey_limit == -1)
404 options->rekey_limit = 0;
405 if (options->rekey_interval == -1)
406 options->rekey_interval = 0;
407 if (options->allow_tcp_forwarding == -1)
408 options->allow_tcp_forwarding = FORWARD_ALLOW;
409 if (options->allow_streamlocal_forwarding == -1)
410 options->allow_streamlocal_forwarding = FORWARD_ALLOW;
411 if (options->allow_agent_forwarding == -1)
412 options->allow_agent_forwarding = 1;
413 if (options->fwd_opts.gateway_ports == -1)
414 options->fwd_opts.gateway_ports = 0;
415 if (options->max_startups == -1)
416 options->max_startups = 100;
417 if (options->max_startups_rate == -1)
418 options->max_startups_rate = 30; /* 30% */
419 if (options->max_startups_begin == -1)
420 options->max_startups_begin = 10;
421 if (options->per_source_max_startups == -1)
422 options->per_source_max_startups = INT_MAX;
423 if (options->per_source_masklen_ipv4 == -1)
424 options->per_source_masklen_ipv4 = 32;
425 if (options->per_source_masklen_ipv6 == -1)
426 options->per_source_masklen_ipv6 = 128;
427 if (options->per_source_penalty.enabled == -1)
428 options->per_source_penalty.enabled = 1;
429 if (options->per_source_penalty.max_sources4 == -1)
430 options->per_source_penalty.max_sources4 = 65536;
431 if (options->per_source_penalty.max_sources6 == -1)
432 options->per_source_penalty.max_sources6 = 65536;
433 if (options->per_source_penalty.overflow_mode == -1)
434 options->per_source_penalty.overflow_mode = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE;
435 if (options->per_source_penalty.overflow_mode6 == -1)
436 options->per_source_penalty.overflow_mode6 = options->per_source_penalty.overflow_mode;
437 if (options->per_source_penalty.penalty_crash == -1)
438 options->per_source_penalty.penalty_crash = 90;
439 if (options->per_source_penalty.penalty_grace == -1)
440 options->per_source_penalty.penalty_grace = 10;
441 if (options->per_source_penalty.penalty_authfail == -1)
442 options->per_source_penalty.penalty_authfail = 5;
443 if (options->per_source_penalty.penalty_noauth == -1)
444 options->per_source_penalty.penalty_noauth = 1;
445 if (options->per_source_penalty.penalty_refuseconnection == -1)
446 options->per_source_penalty.penalty_refuseconnection = 10;
447 if (options->per_source_penalty.penalty_min == -1)
448 options->per_source_penalty.penalty_min = 15;
449 if (options->per_source_penalty.penalty_max == -1)
450 options->per_source_penalty.penalty_max = 600;
451 if (options->max_authtries == -1)
452 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
453 if (options->max_sessions == -1)
454 options->max_sessions = DEFAULT_SESSIONS_MAX;
455 if (options->use_dns == -1)
456 options->use_dns = 0;
457 if (options->client_alive_interval == -1)
458 options->client_alive_interval = 0;
459 if (options->client_alive_count_max == -1)
460 options->client_alive_count_max = 3;
461 if (options->num_authkeys_files == 0) {
462 opt_array_append("[default]", 0, "AuthorizedKeysFiles",
463 &options->authorized_keys_files,
464 &options->num_authkeys_files,
465 _PATH_SSH_USER_PERMITTED_KEYS);
466 opt_array_append("[default]", 0, "AuthorizedKeysFiles",
467 &options->authorized_keys_files,
468 &options->num_authkeys_files,
469 _PATH_SSH_USER_PERMITTED_KEYS2);
471 if (options->permit_tun == -1)
472 options->permit_tun = SSH_TUNMODE_NO;
473 if (options->ip_qos_interactive == -1)
474 options->ip_qos_interactive = IPTOS_DSCP_AF21;
475 if (options->ip_qos_bulk == -1)
476 options->ip_qos_bulk = IPTOS_DSCP_CS1;
477 if (options->version_addendum == NULL)
478 options->version_addendum = xstrdup("");
479 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
480 options->fwd_opts.streamlocal_bind_mask = 0177;
481 if (options->fwd_opts.streamlocal_bind_unlink == -1)
482 options->fwd_opts.streamlocal_bind_unlink = 0;
483 if (options->fingerprint_hash == -1)
484 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
485 if (options->disable_forwarding == -1)
486 options->disable_forwarding = 0;
487 if (options->expose_userauth_info == -1)
488 options->expose_userauth_info = 0;
489 if (options->sk_provider == NULL)
490 options->sk_provider = xstrdup("internal");
491 if (options->required_rsa_size == -1)
492 options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
493 if (options->unused_connection_timeout == -1)
494 options->unused_connection_timeout = 0;
495 if (options->sshd_session_path == NULL)
496 options->sshd_session_path = xstrdup(_PATH_SSHD_SESSION);
497 if (options->sshd_auth_path == NULL)
498 options->sshd_auth_path = xstrdup(_PATH_SSHD_AUTH);
499 if (options->refuse_connection == -1)
500 options->refuse_connection = 0;
502 assemble_algorithms(options);
504 #define CLEAR_ON_NONE(v) \
505 do { \
506 if (option_clear_or_none(v)) { \
507 free(v); \
508 v = NULL; \
510 } while(0)
511 #define CLEAR_ON_NONE_ARRAY(v, nv, none) \
512 do { \
513 if (options->nv == 1 && \
514 strcasecmp(options->v[0], none) == 0) { \
515 free(options->v[0]); \
516 free(options->v); \
517 options->v = NULL; \
518 options->nv = 0; \
520 } while (0)
521 CLEAR_ON_NONE(options->pid_file);
522 CLEAR_ON_NONE(options->xauth_location);
523 CLEAR_ON_NONE(options->banner);
524 CLEAR_ON_NONE(options->trusted_user_ca_keys);
525 CLEAR_ON_NONE(options->revoked_keys_file);
526 CLEAR_ON_NONE(options->sk_provider);
527 CLEAR_ON_NONE(options->authorized_principals_file);
528 CLEAR_ON_NONE(options->adm_forced_command);
529 CLEAR_ON_NONE(options->chroot_directory);
530 CLEAR_ON_NONE(options->routing_domain);
531 CLEAR_ON_NONE(options->host_key_agent);
532 CLEAR_ON_NONE(options->per_source_penalty_exempt);
534 for (i = 0; i < options->num_host_key_files; i++)
535 CLEAR_ON_NONE(options->host_key_files[i]);
536 for (i = 0; i < options->num_host_cert_files; i++)
537 CLEAR_ON_NONE(options->host_cert_files[i]);
539 CLEAR_ON_NONE_ARRAY(channel_timeouts, num_channel_timeouts, "none");
540 CLEAR_ON_NONE_ARRAY(auth_methods, num_auth_methods, "any");
541 #undef CLEAR_ON_NONE
542 #undef CLEAR_ON_NONE_ARRAY
545 /* Keyword tokens. */
546 typedef enum {
547 sBadOption, /* == unknown option */
548 /* Portable-specific options */
549 sUsePAM, sPAMServiceName,
550 /* Standard Options */
551 sPort, sHostKeyFile, sLoginGraceTime,
552 sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
553 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
554 sKerberosGetAFSToken, sPasswordAuthentication,
555 sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
556 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
557 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
558 sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
559 sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
560 sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
561 sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, sModuliFile,
562 sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedAlgorithms,
563 sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
564 sBanner, sUseDNS, sHostbasedAuthentication,
565 sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
566 sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
567 sPerSourcePenalties, sPerSourcePenaltyExemptList,
568 sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
569 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
570 sAcceptEnv, sSetEnv, sPermitTunnel,
571 sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
572 sUsePrivilegeSeparation, sAllowAgentForwarding,
573 sHostCertificate, sInclude,
574 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
575 sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
576 sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
577 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
578 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
579 sStreamLocalBindMask, sStreamLocalBindUnlink,
580 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
581 sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
582 sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout,
583 sSshdSessionPath, sSshdAuthPath, sRefuseConnection,
584 sDeprecated, sIgnore, sUnsupported
585 } ServerOpCodes;
587 #define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */
588 #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
589 #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
590 #define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */
591 #define SSHCFG_MATCH_ONLY 0x08 /* Match only in conditional blocks; internal only */
593 /* Textual representation of the tokens. */
594 static struct {
595 const char *name;
596 ServerOpCodes opcode;
597 u_int flags;
598 } keywords[] = {
599 /* Portable-specific options */
600 #ifdef USE_PAM
601 { "usepam", sUsePAM, SSHCFG_GLOBAL },
602 { "pamservicename", sPAMServiceName, SSHCFG_ALL },
603 #else
604 { "usepam", sUnsupported, SSHCFG_GLOBAL },
605 { "pamservicename", sUnsupported, SSHCFG_ALL },
606 #endif
607 { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
608 /* Standard Options */
609 { "port", sPort, SSHCFG_GLOBAL },
610 { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
611 { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
612 { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
613 { "pidfile", sPidFile, SSHCFG_GLOBAL },
614 { "modulifile", sModuliFile, SSHCFG_GLOBAL },
615 { "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
616 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
617 { "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
618 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
619 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
620 { "loglevel", sLogLevel, SSHCFG_ALL },
621 { "logverbose", sLogVerbose, SSHCFG_ALL },
622 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
623 { "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
624 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
625 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
626 { "hostbasedacceptedalgorithms", sHostbasedAcceptedAlgorithms, SSHCFG_ALL },
627 { "hostbasedacceptedkeytypes", sHostbasedAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
628 { "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
629 { "rsaauthentication", sDeprecated, SSHCFG_ALL },
630 { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
631 { "pubkeyacceptedalgorithms", sPubkeyAcceptedAlgorithms, SSHCFG_ALL },
632 { "pubkeyacceptedkeytypes", sPubkeyAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
633 { "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL },
634 { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
635 #ifdef KRB5
636 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
637 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
638 { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
639 #ifdef USE_AFS
640 { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
641 #else
642 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
643 #endif
644 #else
645 { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
646 { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
647 { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
648 { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
649 #endif
650 { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
651 { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
652 #ifdef GSSAPI
653 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
654 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
655 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
656 #else
657 { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
658 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
659 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
660 #endif
661 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
662 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
663 { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
664 { "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
665 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
666 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
667 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
668 { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
669 #ifdef DISABLE_LASTLOG
670 { "printlastlog", sUnsupported, SSHCFG_GLOBAL },
671 #else
672 { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
673 #endif
674 { "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL },
675 { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
676 { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
677 { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
678 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
679 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
680 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
681 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
682 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
683 { "uselogin", sDeprecated, SSHCFG_GLOBAL },
684 { "compression", sCompression, SSHCFG_GLOBAL },
685 { "rekeylimit", sRekeyLimit, SSHCFG_ALL },
686 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
687 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
688 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
689 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
690 { "allowusers", sAllowUsers, SSHCFG_ALL },
691 { "denyusers", sDenyUsers, SSHCFG_ALL },
692 { "allowgroups", sAllowGroups, SSHCFG_ALL },
693 { "denygroups", sDenyGroups, SSHCFG_ALL },
694 { "ciphers", sCiphers, SSHCFG_GLOBAL },
695 { "macs", sMacs, SSHCFG_GLOBAL },
696 { "protocol", sIgnore, SSHCFG_GLOBAL },
697 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
698 { "subsystem", sSubsystem, SSHCFG_ALL },
699 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
700 { "persourcemaxstartups", sPerSourceMaxStartups, SSHCFG_GLOBAL },
701 { "persourcenetblocksize", sPerSourceNetBlockSize, SSHCFG_GLOBAL },
702 { "persourcepenalties", sPerSourcePenalties, SSHCFG_GLOBAL },
703 { "persourcepenaltyexemptlist", sPerSourcePenaltyExemptList, SSHCFG_GLOBAL },
704 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
705 { "maxsessions", sMaxSessions, SSHCFG_ALL },
706 { "banner", sBanner, SSHCFG_ALL },
707 { "usedns", sUseDNS, SSHCFG_GLOBAL },
708 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
709 { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
710 { "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
711 { "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
712 { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
713 { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
714 { "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
715 { "acceptenv", sAcceptEnv, SSHCFG_ALL },
716 { "setenv", sSetEnv, SSHCFG_ALL },
717 { "permittunnel", sPermitTunnel, SSHCFG_ALL },
718 { "permittty", sPermitTTY, SSHCFG_ALL },
719 { "permituserrc", sPermitUserRC, SSHCFG_ALL },
720 { "match", sMatch, SSHCFG_ALL },
721 { "permitopen", sPermitOpen, SSHCFG_ALL },
722 { "permitlisten", sPermitListen, SSHCFG_ALL },
723 { "forcecommand", sForceCommand, SSHCFG_ALL },
724 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
725 { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
726 { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
727 { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
728 { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
729 { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
730 { "include", sInclude, SSHCFG_ALL },
731 { "ipqos", sIPQoS, SSHCFG_ALL },
732 { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
733 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
734 { "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
735 { "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
736 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
737 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
738 { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
739 { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
740 { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
741 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
742 { "disableforwarding", sDisableForwarding, SSHCFG_ALL },
743 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
744 { "rdomain", sRDomain, SSHCFG_ALL },
745 { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
746 { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
747 { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
748 { "channeltimeout", sChannelTimeout, SSHCFG_ALL },
749 { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
750 { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL },
751 { "sshdauthpath", sSshdAuthPath, SSHCFG_GLOBAL },
752 { "refuseconnection", sRefuseConnection, SSHCFG_ALL },
753 { NULL, sBadOption, 0 }
756 static struct {
757 int val;
758 char *text;
759 } tunmode_desc[] = {
760 { SSH_TUNMODE_NO, "no" },
761 { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
762 { SSH_TUNMODE_ETHERNET, "ethernet" },
763 { SSH_TUNMODE_YES, "yes" },
764 { -1, NULL }
767 /* Returns an opcode name from its number */
769 static const char *
770 lookup_opcode_name(ServerOpCodes code)
772 u_int i;
774 for (i = 0; keywords[i].name != NULL; i++)
775 if (keywords[i].opcode == code)
776 return(keywords[i].name);
777 return "UNKNOWN";
782 * Returns the number of the token pointed to by cp or sBadOption.
785 static ServerOpCodes
786 parse_token(const char *cp, const char *filename,
787 int linenum, u_int *flags)
789 u_int i;
791 for (i = 0; keywords[i].name; i++)
792 if (strcasecmp(cp, keywords[i].name) == 0) {
793 *flags = keywords[i].flags;
794 return keywords[i].opcode;
797 error("%s: line %d: Bad configuration option: %s",
798 filename, linenum, cp);
799 return sBadOption;
802 char *
803 derelativise_path(const char *path)
805 char *expanded, *ret, cwd[PATH_MAX];
807 if (strcasecmp(path, "none") == 0)
808 return xstrdup("none");
809 expanded = tilde_expand_filename(path, getuid());
810 if (path_absolute(expanded))
811 return expanded;
812 if (getcwd(cwd, sizeof(cwd)) == NULL)
813 fatal_f("getcwd: %s", strerror(errno));
814 xasprintf(&ret, "%s/%s", cwd, expanded);
815 free(expanded);
816 return ret;
819 static void
820 add_listen_addr(ServerOptions *options, const char *addr,
821 const char *rdomain, int port)
823 u_int i;
825 if (port > 0)
826 add_one_listen_addr(options, addr, rdomain, port);
827 else {
828 for (i = 0; i < options->num_ports; i++) {
829 add_one_listen_addr(options, addr, rdomain,
830 options->ports[i]);
835 static void
836 add_one_listen_addr(ServerOptions *options, const char *addr,
837 const char *rdomain, int port)
839 struct addrinfo hints, *ai, *aitop;
840 char strport[NI_MAXSERV];
841 int gaierr;
842 u_int i;
844 /* Find listen_addrs entry for this rdomain */
845 for (i = 0; i < options->num_listen_addrs; i++) {
846 if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
847 break;
848 if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
849 continue;
850 if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
851 break;
853 if (i >= options->num_listen_addrs) {
854 /* No entry for this rdomain; allocate one */
855 if (i >= INT_MAX)
856 fatal_f("too many listen addresses");
857 options->listen_addrs = xrecallocarray(options->listen_addrs,
858 options->num_listen_addrs, options->num_listen_addrs + 1,
859 sizeof(*options->listen_addrs));
860 i = options->num_listen_addrs++;
861 if (rdomain != NULL)
862 options->listen_addrs[i].rdomain = xstrdup(rdomain);
864 /* options->listen_addrs[i] points to the addresses for this rdomain */
866 memset(&hints, 0, sizeof(hints));
867 hints.ai_family = options->address_family;
868 hints.ai_socktype = SOCK_STREAM;
869 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
870 snprintf(strport, sizeof strport, "%d", port);
871 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
872 fatal("bad addr or host: %s (%s)",
873 addr ? addr : "<NULL>",
874 ssh_gai_strerror(gaierr));
875 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
877 ai->ai_next = options->listen_addrs[i].addrs;
878 options->listen_addrs[i].addrs = aitop;
881 /* Returns nonzero if the routing domain name is valid */
882 static int
883 valid_rdomain(const char *name)
885 #if defined(HAVE_SYS_VALID_RDOMAIN)
886 return sys_valid_rdomain(name);
887 #elif defined(__OpenBSD__)
888 const char *errstr;
889 long long num;
890 struct rt_tableinfo info;
891 int mib[6];
892 size_t miblen = sizeof(mib);
894 if (name == NULL)
895 return 1;
897 num = strtonum(name, 0, 255, &errstr);
898 if (errstr != NULL)
899 return 0;
901 /* Check whether the table actually exists */
902 memset(mib, 0, sizeof(mib));
903 mib[0] = CTL_NET;
904 mib[1] = PF_ROUTE;
905 mib[4] = NET_RT_TABLE;
906 mib[5] = (int)num;
907 if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
908 return 0;
910 return 1;
911 #else /* defined(__OpenBSD__) */
912 error("Routing domains are not supported on this platform");
913 return 0;
914 #endif
918 * Queue a ListenAddress to be processed once we have all of the Ports
919 * and AddressFamily options.
921 static void
922 queue_listen_addr(ServerOptions *options, const char *addr,
923 const char *rdomain, int port)
925 struct queued_listenaddr *qla;
927 options->queued_listen_addrs = xrecallocarray(
928 options->queued_listen_addrs,
929 options->num_queued_listens, options->num_queued_listens + 1,
930 sizeof(*options->queued_listen_addrs));
931 qla = &options->queued_listen_addrs[options->num_queued_listens++];
932 qla->addr = xstrdup(addr);
933 qla->port = port;
934 qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
938 * Process queued (text) ListenAddress entries.
940 static void
941 process_queued_listen_addrs(ServerOptions *options)
943 u_int i;
944 struct queued_listenaddr *qla;
946 if (options->num_ports == 0)
947 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
948 if (options->address_family == -1)
949 options->address_family = AF_UNSPEC;
951 for (i = 0; i < options->num_queued_listens; i++) {
952 qla = &options->queued_listen_addrs[i];
953 add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
954 free(qla->addr);
955 free(qla->rdomain);
957 free(options->queued_listen_addrs);
958 options->queued_listen_addrs = NULL;
959 options->num_queued_listens = 0;
963 * The strategy for the Match blocks is that the config file is parsed twice.
965 * The first time is at startup. activep is initialized to 1 and the
966 * directives in the global context are processed and acted on. Hitting a
967 * Match directive unsets activep and the directives inside the block are
968 * checked for syntax only.
970 * The second time is after a connection has been established but before
971 * authentication. activep is initialized to 2 and global config directives
972 * are ignored since they have already been processed. If the criteria in a
973 * Match block is met, activep is set and the subsequent directives
974 * processed and actioned until EOF or another Match block unsets it. Any
975 * options set are copied into the main server config.
977 * Potential additions/improvements:
978 * - Add Match support for pre-kex directives, eg. Ciphers.
980 * - Add a Tag directive (idea from David Leonard) ala pf, eg:
981 * Match Address 192.168.0.*
982 * Tag trusted
983 * Match Group wheel
984 * Tag trusted
985 * Match Tag trusted
986 * AllowTcpForwarding yes
987 * GatewayPorts clientspecified
988 * [...]
990 * - Add a PermittedChannelRequests directive
991 * Match Group shell
992 * PermittedChannelRequests session,forwarded-tcpip
995 static int
996 match_cfg_line_group(const char *grps, int line, const char *user)
998 int result = 0;
999 struct passwd *pw;
1001 if (user == NULL)
1002 goto out;
1004 if ((pw = getpwnam(user)) == NULL) {
1005 debug("Can't match group at line %d because user %.100s does "
1006 "not exist", line, user);
1007 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
1008 debug("Can't Match group because user %.100s not in any group "
1009 "at line %d", user, line);
1010 } else if (ga_match_pattern_list(grps) != 1) {
1011 debug("user %.100s does not match group list %.100s at line %d",
1012 user, grps, line);
1013 } else {
1014 debug("user %.100s matched group list %.100s at line %d", user,
1015 grps, line);
1016 result = 1;
1018 out:
1019 ga_free();
1020 return result;
1023 static void
1024 match_test_missing_fatal(const char *criteria, const char *attrib)
1026 fatal("'Match %s' in configuration but '%s' not in connection "
1027 "test specification.", criteria, attrib);
1031 * All of the attributes on a single Match line are ANDed together, so we need
1032 * to check every attribute and set the result to zero if any attribute does
1033 * not match.
1035 static int
1036 match_cfg_line(const char *full_line, int *acp, char ***avp,
1037 int line, struct connection_info *ci)
1039 int result = 1, attributes = 0, port;
1040 char *arg, *attrib = NULL, *oattrib;
1042 if (ci == NULL)
1043 debug3("checking syntax for 'Match %s'", full_line);
1044 else {
1045 debug3("checking match for '%s' user %s%s host %s addr %s "
1046 "laddr %s lport %d", full_line,
1047 ci->user ? ci->user : "(null)",
1048 ci->user_invalid ? " (invalid)" : "",
1049 ci->host ? ci->host : "(null)",
1050 ci->address ? ci->address : "(null)",
1051 ci->laddress ? ci->laddress : "(null)", ci->lport);
1054 while ((oattrib = argv_next(acp, avp)) != NULL) {
1055 attrib = xstrdup(oattrib);
1056 /* Terminate on comment */
1057 if (*attrib == '#') {
1058 argv_consume(acp); /* mark all arguments consumed */
1059 break;
1061 arg = NULL;
1062 attributes++;
1063 /* Criterion "all" has no argument and must appear alone */
1064 if (strcasecmp(attrib, "all") == 0) {
1065 if (attributes > 1 ||
1066 ((arg = argv_next(acp, avp)) != NULL &&
1067 *arg != '\0' && *arg != '#')) {
1068 error("'all' cannot be combined with other "
1069 "Match attributes");
1070 result = -1;
1071 goto out;
1073 if (arg != NULL && *arg == '#')
1074 argv_consume(acp); /* consume remaining args */
1075 result = 1;
1076 goto out;
1078 /* Criterion "invalid-user" also has no argument */
1079 if (strcasecmp(attrib, "invalid-user") == 0) {
1080 if (ci == NULL)
1081 continue;
1082 if (ci->user_invalid == 0)
1083 result = 0;
1084 else
1085 debug("matched invalid-user at line %d", line);
1086 continue;
1089 /* Keep this list in sync with below */
1090 if (strprefix(attrib, "user=", 1) != NULL ||
1091 strprefix(attrib, "group=", 1) != NULL ||
1092 strprefix(attrib, "host=", 1) != NULL ||
1093 strprefix(attrib, "address=", 1) != NULL ||
1094 strprefix(attrib, "localaddress=", 1) != NULL ||
1095 strprefix(attrib, "localport=", 1) != NULL ||
1096 strprefix(attrib, "rdomain=", 1) != NULL) {
1097 arg = strchr(attrib, '=');
1098 *(arg++) = '\0';
1099 } else {
1100 arg = argv_next(acp, avp);
1103 /* All other criteria require an argument */
1104 if (arg == NULL || *arg == '\0' || *arg == '#') {
1105 error("Missing Match criteria for %s", attrib);
1106 result = -1;
1107 goto out;
1109 if (strcasecmp(attrib, "user") == 0) {
1110 if (ci == NULL || (ci->test && ci->user == NULL)) {
1111 result = 0;
1112 continue;
1114 if (ci->user == NULL)
1115 match_test_missing_fatal("User", "user");
1116 if (match_usergroup_pattern_list(ci->user, arg) != 1)
1117 result = 0;
1118 else
1119 debug("user %.100s matched 'User %.100s' at "
1120 "line %d", ci->user, arg, line);
1121 } else if (strcasecmp(attrib, "group") == 0) {
1122 if (ci == NULL || (ci->test && ci->user == NULL)) {
1123 result = 0;
1124 continue;
1126 if (ci->user == NULL)
1127 match_test_missing_fatal("Group", "user");
1128 switch (match_cfg_line_group(arg, line, ci->user)) {
1129 case -1:
1130 result = -1;
1131 goto out;
1132 case 0:
1133 result = 0;
1135 } else if (strcasecmp(attrib, "host") == 0) {
1136 if (ci == NULL || (ci->test && ci->host == NULL)) {
1137 result = 0;
1138 continue;
1140 if (ci->host == NULL)
1141 match_test_missing_fatal("Host", "host");
1142 if (match_hostname(ci->host, arg) != 1)
1143 result = 0;
1144 else
1145 debug("connection from %.100s matched 'Host "
1146 "%.100s' at line %d", ci->host, arg, line);
1147 } else if (strcasecmp(attrib, "address") == 0) {
1148 if (ci == NULL || (ci->test && ci->address == NULL)) {
1149 if (addr_match_list(NULL, arg) != 0)
1150 fatal("Invalid Match address argument "
1151 "'%s' at line %d", arg, line);
1152 result = 0;
1153 continue;
1155 if (ci->address == NULL)
1156 match_test_missing_fatal("Address", "addr");
1157 switch (addr_match_list(ci->address, arg)) {
1158 case 1:
1159 debug("connection from %.100s matched 'Address "
1160 "%.100s' at line %d", ci->address, arg, line);
1161 break;
1162 case 0:
1163 case -1:
1164 result = 0;
1165 break;
1166 case -2:
1167 result = -1;
1168 goto out;
1170 } else if (strcasecmp(attrib, "localaddress") == 0){
1171 if (ci == NULL || (ci->test && ci->laddress == NULL)) {
1172 if (addr_match_list(NULL, arg) != 0)
1173 fatal("Invalid Match localaddress "
1174 "argument '%s' at line %d", arg,
1175 line);
1176 result = 0;
1177 continue;
1179 if (ci->laddress == NULL)
1180 match_test_missing_fatal("LocalAddress",
1181 "laddr");
1182 switch (addr_match_list(ci->laddress, arg)) {
1183 case 1:
1184 debug("connection from %.100s matched "
1185 "'LocalAddress %.100s' at line %d",
1186 ci->laddress, arg, line);
1187 break;
1188 case 0:
1189 case -1:
1190 result = 0;
1191 break;
1192 case -2:
1193 result = -1;
1194 goto out;
1196 } else if (strcasecmp(attrib, "localport") == 0) {
1197 if ((port = a2port(arg)) == -1) {
1198 error("Invalid LocalPort '%s' on Match line",
1199 arg);
1200 result = -1;
1201 goto out;
1203 if (ci == NULL || (ci->test && ci->lport == -1)) {
1204 result = 0;
1205 continue;
1207 if (ci->lport == 0)
1208 match_test_missing_fatal("LocalPort", "lport");
1209 /* TODO support port lists */
1210 if (port == ci->lport)
1211 debug("connection from %.100s matched "
1212 "'LocalPort %d' at line %d",
1213 ci->laddress, port, line);
1214 else
1215 result = 0;
1216 } else if (strcasecmp(attrib, "rdomain") == 0) {
1217 if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
1218 result = 0;
1219 continue;
1221 if (ci->rdomain == NULL)
1222 match_test_missing_fatal("RDomain", "rdomain");
1223 if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1224 result = 0;
1225 else
1226 debug("user %.100s matched 'RDomain %.100s' at "
1227 "line %d", ci->rdomain, arg, line);
1228 } else {
1229 error("Unsupported Match attribute %s", oattrib);
1230 result = -1;
1231 goto out;
1233 free(attrib);
1234 attrib = NULL;
1236 if (attributes == 0) {
1237 error("One or more attributes required for Match");
1238 return -1;
1240 out:
1241 if (ci != NULL && result != -1)
1242 debug3("match %sfound", result ? "" : "not ");
1243 free(attrib);
1244 return result;
1247 #define WHITESPACE " \t\r\n"
1249 /* Multistate option parsing */
1250 struct multistate {
1251 char *key;
1252 int value;
1254 static const struct multistate multistate_flag[] = {
1255 { "yes", 1 },
1256 { "no", 0 },
1257 { NULL, -1 }
1259 static const struct multistate multistate_ignore_rhosts[] = {
1260 { "yes", IGNORE_RHOSTS_YES },
1261 { "no", IGNORE_RHOSTS_NO },
1262 { "shosts-only", IGNORE_RHOSTS_SHOSTS },
1263 { NULL, -1 }
1265 static const struct multistate multistate_addressfamily[] = {
1266 { "inet", AF_INET },
1267 { "inet6", AF_INET6 },
1268 { "any", AF_UNSPEC },
1269 { NULL, -1 }
1271 static const struct multistate multistate_permitrootlogin[] = {
1272 { "without-password", PERMIT_NO_PASSWD },
1273 { "prohibit-password", PERMIT_NO_PASSWD },
1274 { "forced-commands-only", PERMIT_FORCED_ONLY },
1275 { "yes", PERMIT_YES },
1276 { "no", PERMIT_NO },
1277 { NULL, -1 }
1279 static const struct multistate multistate_compression[] = {
1280 #ifdef WITH_ZLIB
1281 { "yes", COMP_DELAYED },
1282 { "delayed", COMP_DELAYED },
1283 #endif
1284 { "no", COMP_NONE },
1285 { NULL, -1 }
1287 static const struct multistate multistate_gatewayports[] = {
1288 { "clientspecified", 2 },
1289 { "yes", 1 },
1290 { "no", 0 },
1291 { NULL, -1 }
1293 static const struct multistate multistate_tcpfwd[] = {
1294 { "yes", FORWARD_ALLOW },
1295 { "all", FORWARD_ALLOW },
1296 { "no", FORWARD_DENY },
1297 { "remote", FORWARD_REMOTE },
1298 { "local", FORWARD_LOCAL },
1299 { NULL, -1 }
1302 static int
1303 process_server_config_line_depth(ServerOptions *options, char *line,
1304 const char *filename, int linenum, int *activep,
1305 struct connection_info *connectinfo, int *inc_flags, int depth,
1306 struct include_list *includes)
1308 char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
1309 int cmdline = 0, *intptr, value, value2, n, port, oactive, r;
1310 int ca_only = 0, found = 0;
1311 SyslogFacility *log_facility_ptr;
1312 LogLevel *log_level_ptr;
1313 ServerOpCodes opcode;
1314 u_int i, *uintptr, flags = 0;
1315 size_t len;
1316 long long val64;
1317 const struct multistate *multistate_ptr;
1318 const char *errstr;
1319 struct include_item *item;
1320 glob_t gbuf;
1321 char **oav = NULL, **av;
1322 int oac = 0, ac;
1323 int ret = -1;
1324 char **strs = NULL; /* string array arguments; freed implicitly */
1325 u_int nstrs = 0;
1327 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1328 if ((len = strlen(line)) == 0)
1329 return 0;
1330 for (len--; len > 0; len--) {
1331 if (strchr(WHITESPACE "\f", line[len]) == NULL)
1332 break;
1333 line[len] = '\0';
1336 str = line;
1337 if ((keyword = strdelim(&str)) == NULL)
1338 return 0;
1339 /* Ignore leading whitespace */
1340 if (*keyword == '\0')
1341 keyword = strdelim(&str);
1342 if (!keyword || !*keyword || *keyword == '#')
1343 return 0;
1344 if (str == NULL || *str == '\0') {
1345 error("%s line %d: no argument after keyword \"%s\"",
1346 filename, linenum, keyword);
1347 return -1;
1349 intptr = NULL;
1350 charptr = NULL;
1351 opcode = parse_token(keyword, filename, linenum, &flags);
1353 if (argv_split(str, &oac, &oav, 1) != 0) {
1354 error("%s line %d: invalid quotes", filename, linenum);
1355 return -1;
1357 ac = oac;
1358 av = oav;
1360 if (activep == NULL) { /* We are processing a command line directive */
1361 cmdline = 1;
1362 activep = &cmdline;
1364 if (*activep && opcode != sMatch && opcode != sInclude)
1365 debug3("%s:%d setting %s %s", filename, linenum, keyword, str);
1366 if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1367 if (connectinfo == NULL) {
1368 fatal("%s line %d: Directive '%s' is not allowed "
1369 "within a Match block", filename, linenum, keyword);
1370 } else { /* this is a directive we have already processed */
1371 ret = 0;
1372 goto out;
1376 switch (opcode) {
1377 /* Portable-specific options */
1378 case sUsePAM:
1379 intptr = &options->use_pam;
1380 goto parse_flag;
1381 case sPAMServiceName:
1382 charptr = &options->pam_service_name;
1383 arg = argv_next(&ac, &av);
1384 if (!arg || *arg == '\0') {
1385 fatal("%s line %d: missing argument.",
1386 filename, linenum);
1388 if (*activep && *charptr == NULL)
1389 *charptr = xstrdup(arg);
1390 break;
1392 /* Standard Options */
1393 case sBadOption:
1394 goto out;
1395 case sPort:
1396 /* ignore ports from configfile if cmdline specifies ports */
1397 if (options->ports_from_cmdline) {
1398 argv_consume(&ac);
1399 break;
1401 if (options->num_ports >= MAX_PORTS)
1402 fatal("%s line %d: too many ports.",
1403 filename, linenum);
1404 arg = argv_next(&ac, &av);
1405 if (!arg || *arg == '\0')
1406 fatal("%s line %d: missing port number.",
1407 filename, linenum);
1408 options->ports[options->num_ports++] = a2port(arg);
1409 if (options->ports[options->num_ports-1] <= 0)
1410 fatal("%s line %d: Badly formatted port number.",
1411 filename, linenum);
1412 break;
1414 case sLoginGraceTime:
1415 intptr = &options->login_grace_time;
1416 parse_time:
1417 arg = argv_next(&ac, &av);
1418 if (!arg || *arg == '\0')
1419 fatal("%s line %d: missing time value.",
1420 filename, linenum);
1421 if ((value = convtime(arg)) == -1)
1422 fatal("%s line %d: invalid time value.",
1423 filename, linenum);
1424 if (*activep && *intptr == -1)
1425 *intptr = value;
1426 break;
1428 case sListenAddress:
1429 arg = argv_next(&ac, &av);
1430 if (arg == NULL || *arg == '\0')
1431 fatal("%s line %d: missing address",
1432 filename, linenum);
1433 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
1434 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1435 && strchr(p+1, ':') != NULL) {
1436 port = 0;
1437 p = arg;
1438 } else {
1439 arg2 = NULL;
1440 p = hpdelim(&arg);
1441 if (p == NULL)
1442 fatal("%s line %d: bad address:port usage",
1443 filename, linenum);
1444 p = cleanhostname(p);
1445 if (arg == NULL)
1446 port = 0;
1447 else if ((port = a2port(arg)) <= 0)
1448 fatal("%s line %d: bad port number",
1449 filename, linenum);
1451 /* Optional routing table */
1452 arg2 = NULL;
1453 if ((arg = argv_next(&ac, &av)) != NULL) {
1454 if (strcmp(arg, "rdomain") != 0 ||
1455 (arg2 = argv_next(&ac, &av)) == NULL)
1456 fatal("%s line %d: bad ListenAddress syntax",
1457 filename, linenum);
1458 if (!valid_rdomain(arg2))
1459 fatal("%s line %d: bad routing domain",
1460 filename, linenum);
1462 queue_listen_addr(options, p, arg2, port);
1464 break;
1466 case sAddressFamily:
1467 intptr = &options->address_family;
1468 multistate_ptr = multistate_addressfamily;
1469 parse_multistate:
1470 arg = argv_next(&ac, &av);
1471 if (!arg || *arg == '\0')
1472 fatal("%s line %d: missing argument.",
1473 filename, linenum);
1474 value = -1;
1475 for (i = 0; multistate_ptr[i].key != NULL; i++) {
1476 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1477 value = multistate_ptr[i].value;
1478 break;
1481 if (value == -1)
1482 fatal("%s line %d: unsupported option \"%s\".",
1483 filename, linenum, arg);
1484 if (*activep && *intptr == -1)
1485 *intptr = value;
1486 break;
1488 case sHostKeyFile:
1489 arg = argv_next(&ac, &av);
1490 if (!arg || *arg == '\0')
1491 fatal("%s line %d: missing file name.",
1492 filename, linenum);
1493 if (*activep) {
1494 servconf_add_hostkey(filename, linenum,
1495 options, arg, 1);
1497 break;
1499 case sHostKeyAgent:
1500 charptr = &options->host_key_agent;
1501 arg = argv_next(&ac, &av);
1502 if (!arg || *arg == '\0')
1503 fatal("%s line %d: missing socket name.",
1504 filename, linenum);
1505 if (*activep && *charptr == NULL)
1506 *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1507 xstrdup(arg) : derelativise_path(arg);
1508 break;
1510 case sHostCertificate:
1511 arg = argv_next(&ac, &av);
1512 if (!arg || *arg == '\0')
1513 fatal("%s line %d: missing file name.",
1514 filename, linenum);
1515 if (*activep)
1516 servconf_add_hostcert(filename, linenum, options, arg);
1517 break;
1519 case sPidFile:
1520 charptr = &options->pid_file;
1521 parse_filename:
1522 arg = argv_next(&ac, &av);
1523 if (!arg || *arg == '\0')
1524 fatal("%s line %d: missing file name.",
1525 filename, linenum);
1526 if (*activep && *charptr == NULL) {
1527 *charptr = derelativise_path(arg);
1528 /* increase optional counter */
1529 if (intptr != NULL)
1530 *intptr = *intptr + 1;
1532 break;
1534 case sModuliFile:
1535 charptr = &options->moduli_file;
1536 goto parse_filename;
1538 case sPermitRootLogin:
1539 intptr = &options->permit_root_login;
1540 multistate_ptr = multistate_permitrootlogin;
1541 goto parse_multistate;
1543 case sIgnoreRhosts:
1544 intptr = &options->ignore_rhosts;
1545 multistate_ptr = multistate_ignore_rhosts;
1546 goto parse_multistate;
1548 case sIgnoreUserKnownHosts:
1549 intptr = &options->ignore_user_known_hosts;
1550 parse_flag:
1551 multistate_ptr = multistate_flag;
1552 goto parse_multistate;
1554 case sHostbasedAuthentication:
1555 intptr = &options->hostbased_authentication;
1556 goto parse_flag;
1558 case sHostbasedUsesNameFromPacketOnly:
1559 intptr = &options->hostbased_uses_name_from_packet_only;
1560 goto parse_flag;
1562 case sHostbasedAcceptedAlgorithms:
1563 charptr = &options->hostbased_accepted_algos;
1564 ca_only = 0;
1565 parse_pubkey_algos:
1566 arg = argv_next(&ac, &av);
1567 if (!arg || *arg == '\0')
1568 fatal("%s line %d: Missing argument.",
1569 filename, linenum);
1570 if (*arg != '-' &&
1571 !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1572 arg + 1 : arg, 1, ca_only))
1573 fatal("%s line %d: Bad key types '%s'.",
1574 filename, linenum, arg ? arg : "<NONE>");
1575 if (*activep && *charptr == NULL)
1576 *charptr = xstrdup(arg);
1577 break;
1579 case sHostKeyAlgorithms:
1580 charptr = &options->hostkeyalgorithms;
1581 ca_only = 0;
1582 goto parse_pubkey_algos;
1584 case sCASignatureAlgorithms:
1585 charptr = &options->ca_sign_algorithms;
1586 ca_only = 1;
1587 goto parse_pubkey_algos;
1589 case sPubkeyAuthentication:
1590 intptr = &options->pubkey_authentication;
1591 ca_only = 0;
1592 goto parse_flag;
1594 case sPubkeyAcceptedAlgorithms:
1595 charptr = &options->pubkey_accepted_algos;
1596 ca_only = 0;
1597 goto parse_pubkey_algos;
1599 case sPubkeyAuthOptions:
1600 intptr = &options->pubkey_auth_options;
1601 value = 0;
1602 while ((arg = argv_next(&ac, &av)) != NULL) {
1603 if (strcasecmp(arg, "none") == 0)
1604 continue;
1605 if (strcasecmp(arg, "touch-required") == 0)
1606 value |= PUBKEYAUTH_TOUCH_REQUIRED;
1607 else if (strcasecmp(arg, "verify-required") == 0)
1608 value |= PUBKEYAUTH_VERIFY_REQUIRED;
1609 else {
1610 error("%s line %d: unsupported %s option %s",
1611 filename, linenum, keyword, arg);
1612 goto out;
1615 if (*activep && *intptr == -1)
1616 *intptr = value;
1617 break;
1619 case sKerberosAuthentication:
1620 intptr = &options->kerberos_authentication;
1621 goto parse_flag;
1623 case sKerberosOrLocalPasswd:
1624 intptr = &options->kerberos_or_local_passwd;
1625 goto parse_flag;
1627 case sKerberosTicketCleanup:
1628 intptr = &options->kerberos_ticket_cleanup;
1629 goto parse_flag;
1631 case sKerberosGetAFSToken:
1632 intptr = &options->kerberos_get_afs_token;
1633 goto parse_flag;
1635 case sGssAuthentication:
1636 intptr = &options->gss_authentication;
1637 goto parse_flag;
1639 case sGssCleanupCreds:
1640 intptr = &options->gss_cleanup_creds;
1641 goto parse_flag;
1643 case sGssStrictAcceptor:
1644 intptr = &options->gss_strict_acceptor;
1645 goto parse_flag;
1647 case sPasswordAuthentication:
1648 intptr = &options->password_authentication;
1649 goto parse_flag;
1651 case sKbdInteractiveAuthentication:
1652 intptr = &options->kbd_interactive_authentication;
1653 goto parse_flag;
1655 case sPrintMotd:
1656 intptr = &options->print_motd;
1657 goto parse_flag;
1659 case sPrintLastLog:
1660 intptr = &options->print_lastlog;
1661 goto parse_flag;
1663 case sX11Forwarding:
1664 intptr = &options->x11_forwarding;
1665 goto parse_flag;
1667 case sX11DisplayOffset:
1668 intptr = &options->x11_display_offset;
1669 parse_int:
1670 arg = argv_next(&ac, &av);
1671 if ((errstr = atoi_err(arg, &value)) != NULL)
1672 fatal("%s line %d: %s integer value %s.",
1673 filename, linenum, keyword, errstr);
1674 if (*activep && *intptr == -1)
1675 *intptr = value;
1676 break;
1678 case sX11UseLocalhost:
1679 intptr = &options->x11_use_localhost;
1680 goto parse_flag;
1682 case sXAuthLocation:
1683 charptr = &options->xauth_location;
1684 goto parse_filename;
1686 case sPermitTTY:
1687 intptr = &options->permit_tty;
1688 goto parse_flag;
1690 case sPermitUserRC:
1691 intptr = &options->permit_user_rc;
1692 goto parse_flag;
1694 case sStrictModes:
1695 intptr = &options->strict_modes;
1696 goto parse_flag;
1698 case sTCPKeepAlive:
1699 intptr = &options->tcp_keep_alive;
1700 goto parse_flag;
1702 case sEmptyPasswd:
1703 intptr = &options->permit_empty_passwd;
1704 goto parse_flag;
1706 case sPermitUserEnvironment:
1707 intptr = &options->permit_user_env;
1708 charptr = &options->permit_user_env_allowlist;
1709 arg = argv_next(&ac, &av);
1710 if (!arg || *arg == '\0')
1711 fatal("%s line %d: %s missing argument.",
1712 filename, linenum, keyword);
1713 value = 0;
1714 p = NULL;
1715 if (strcmp(arg, "yes") == 0)
1716 value = 1;
1717 else if (strcmp(arg, "no") == 0)
1718 value = 0;
1719 else {
1720 /* Pattern-list specified */
1721 value = 1;
1722 p = xstrdup(arg);
1724 if (*activep && *intptr == -1) {
1725 *intptr = value;
1726 *charptr = p;
1727 p = NULL;
1729 free(p);
1730 break;
1732 case sCompression:
1733 intptr = &options->compression;
1734 multistate_ptr = multistate_compression;
1735 goto parse_multistate;
1737 case sRekeyLimit:
1738 arg = argv_next(&ac, &av);
1739 if (!arg || *arg == '\0')
1740 fatal("%s line %d: %s missing argument.",
1741 filename, linenum, keyword);
1742 if (strcmp(arg, "default") == 0) {
1743 val64 = 0;
1744 } else {
1745 if (scan_scaled(arg, &val64) == -1)
1746 fatal("%.200s line %d: Bad %s number '%s': %s",
1747 filename, linenum, keyword,
1748 arg, strerror(errno));
1749 if (val64 != 0 && val64 < 16)
1750 fatal("%.200s line %d: %s too small",
1751 filename, linenum, keyword);
1753 if (*activep && options->rekey_limit == -1)
1754 options->rekey_limit = val64;
1755 if (ac != 0) { /* optional rekey interval present */
1756 if (strcmp(av[0], "none") == 0) {
1757 (void)argv_next(&ac, &av); /* discard */
1758 break;
1760 intptr = &options->rekey_interval;
1761 goto parse_time;
1763 break;
1765 case sGatewayPorts:
1766 intptr = &options->fwd_opts.gateway_ports;
1767 multistate_ptr = multistate_gatewayports;
1768 goto parse_multistate;
1770 case sUseDNS:
1771 intptr = &options->use_dns;
1772 goto parse_flag;
1774 case sLogFacility:
1775 log_facility_ptr = &options->log_facility;
1776 arg = argv_next(&ac, &av);
1777 value = log_facility_number(arg);
1778 if (value == SYSLOG_FACILITY_NOT_SET)
1779 fatal("%.200s line %d: unsupported log facility '%s'",
1780 filename, linenum, arg ? arg : "<NONE>");
1781 if (*log_facility_ptr == -1)
1782 *log_facility_ptr = (SyslogFacility) value;
1783 break;
1785 case sLogLevel:
1786 log_level_ptr = &options->log_level;
1787 arg = argv_next(&ac, &av);
1788 value = log_level_number(arg);
1789 if (value == SYSLOG_LEVEL_NOT_SET)
1790 fatal("%.200s line %d: unsupported log level '%s'",
1791 filename, linenum, arg ? arg : "<NONE>");
1792 if (*activep && *log_level_ptr == -1)
1793 *log_level_ptr = (LogLevel) value;
1794 break;
1796 case sLogVerbose:
1797 found = options->num_log_verbose == 0;
1798 while ((arg = argv_next(&ac, &av)) != NULL) {
1799 if (*arg == '\0') {
1800 error("%s line %d: keyword %s empty argument",
1801 filename, linenum, keyword);
1802 goto out;
1804 /* Allow "none" only in first position */
1805 if (strcasecmp(arg, "none") == 0) {
1806 if (nstrs > 0 || ac > 0) {
1807 error("%s line %d: keyword %s \"none\" "
1808 "argument must appear alone.",
1809 filename, linenum, keyword);
1810 goto out;
1813 opt_array_append(filename, linenum, keyword,
1814 &strs, &nstrs, arg);
1816 if (nstrs == 0) {
1817 fatal("%s line %d: no %s specified",
1818 filename, linenum, keyword);
1820 if (found && *activep) {
1821 options->log_verbose = strs;
1822 options->num_log_verbose = nstrs;
1823 strs = NULL; /* transferred */
1824 nstrs = 0;
1826 break;
1828 case sAllowTcpForwarding:
1829 intptr = &options->allow_tcp_forwarding;
1830 multistate_ptr = multistate_tcpfwd;
1831 goto parse_multistate;
1833 case sAllowStreamLocalForwarding:
1834 intptr = &options->allow_streamlocal_forwarding;
1835 multistate_ptr = multistate_tcpfwd;
1836 goto parse_multistate;
1838 case sAllowAgentForwarding:
1839 intptr = &options->allow_agent_forwarding;
1840 goto parse_flag;
1842 case sDisableForwarding:
1843 intptr = &options->disable_forwarding;
1844 goto parse_flag;
1846 case sAllowUsers:
1847 chararrayptr = &options->allow_users;
1848 uintptr = &options->num_allow_users;
1849 parse_allowdenyusers:
1850 /* XXX appends to list; doesn't respect first-match-wins */
1851 while ((arg = argv_next(&ac, &av)) != NULL) {
1852 if (*arg == '\0' ||
1853 match_user(NULL, NULL, NULL, arg) == -1)
1854 fatal("%s line %d: invalid %s pattern: \"%s\"",
1855 filename, linenum, keyword, arg);
1856 found = 1;
1857 if (!*activep)
1858 continue;
1859 opt_array_append(filename, linenum, keyword,
1860 chararrayptr, uintptr, arg);
1862 if (!found) {
1863 fatal("%s line %d: no %s specified",
1864 filename, linenum, keyword);
1866 break;
1868 case sDenyUsers:
1869 chararrayptr = &options->deny_users;
1870 uintptr = &options->num_deny_users;
1871 goto parse_allowdenyusers;
1873 case sAllowGroups:
1874 chararrayptr = &options->allow_groups;
1875 uintptr = &options->num_allow_groups;
1876 /* XXX appends to list; doesn't respect first-match-wins */
1877 parse_allowdenygroups:
1878 while ((arg = argv_next(&ac, &av)) != NULL) {
1879 if (*arg == '\0')
1880 fatal("%s line %d: empty %s pattern",
1881 filename, linenum, keyword);
1882 found = 1;
1883 if (!*activep)
1884 continue;
1885 opt_array_append(filename, linenum, keyword,
1886 chararrayptr, uintptr, arg);
1888 if (!found) {
1889 fatal("%s line %d: no %s specified",
1890 filename, linenum, keyword);
1892 break;
1894 case sDenyGroups:
1895 chararrayptr = &options->deny_groups;
1896 uintptr = &options->num_deny_groups;
1897 goto parse_allowdenygroups;
1899 case sCiphers:
1900 arg = argv_next(&ac, &av);
1901 if (!arg || *arg == '\0')
1902 fatal("%s line %d: %s missing argument.",
1903 filename, linenum, keyword);
1904 if (*arg != '-' &&
1905 !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1906 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1907 filename, linenum, arg ? arg : "<NONE>");
1908 if (options->ciphers == NULL)
1909 options->ciphers = xstrdup(arg);
1910 break;
1912 case sMacs:
1913 arg = argv_next(&ac, &av);
1914 if (!arg || *arg == '\0')
1915 fatal("%s line %d: %s missing argument.",
1916 filename, linenum, keyword);
1917 if (*arg != '-' &&
1918 !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1919 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1920 filename, linenum, arg ? arg : "<NONE>");
1921 if (options->macs == NULL)
1922 options->macs = xstrdup(arg);
1923 break;
1925 case sKexAlgorithms:
1926 arg = argv_next(&ac, &av);
1927 if (!arg || *arg == '\0')
1928 fatal("%s line %d: %s missing argument.",
1929 filename, linenum, keyword);
1930 if (*arg != '-' &&
1931 !kex_names_valid(*arg == '+' || *arg == '^' ?
1932 arg + 1 : arg))
1933 fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1934 filename, linenum, arg ? arg : "<NONE>");
1935 if (options->kex_algorithms == NULL)
1936 options->kex_algorithms = xstrdup(arg);
1937 break;
1939 case sSubsystem:
1940 arg = argv_next(&ac, &av);
1941 if (!arg || *arg == '\0')
1942 fatal("%s line %d: %s missing argument.",
1943 filename, linenum, keyword);
1944 if (!*activep) {
1945 argv_consume(&ac);
1946 break;
1948 found = 0;
1949 for (i = 0; i < options->num_subsystems; i++) {
1950 if (strcmp(arg, options->subsystem_name[i]) == 0) {
1951 found = 1;
1952 break;
1955 if (found) {
1956 debug("%s line %d: Subsystem '%s' already defined.",
1957 filename, linenum, arg);
1958 argv_consume(&ac);
1959 break;
1961 options->subsystem_name = xrecallocarray(
1962 options->subsystem_name, options->num_subsystems,
1963 options->num_subsystems + 1,
1964 sizeof(*options->subsystem_name));
1965 options->subsystem_command = xrecallocarray(
1966 options->subsystem_command, options->num_subsystems,
1967 options->num_subsystems + 1,
1968 sizeof(*options->subsystem_command));
1969 options->subsystem_args = xrecallocarray(
1970 options->subsystem_args, options->num_subsystems,
1971 options->num_subsystems + 1,
1972 sizeof(*options->subsystem_args));
1973 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1974 arg = argv_next(&ac, &av);
1975 if (!arg || *arg == '\0') {
1976 fatal("%s line %d: Missing subsystem command.",
1977 filename, linenum);
1979 options->subsystem_command[options->num_subsystems] =
1980 xstrdup(arg);
1981 /* Collect arguments (separate to executable) */
1982 arg = argv_assemble(1, &arg); /* quote command correctly */
1983 arg2 = argv_assemble(ac, av); /* rest of command */
1984 xasprintf(&options->subsystem_args[options->num_subsystems],
1985 "%s%s%s", arg, *arg2 == '\0' ? "" : " ", arg2);
1986 free(arg2);
1987 free(arg);
1988 argv_consume(&ac);
1989 options->num_subsystems++;
1990 break;
1992 case sMaxStartups:
1993 arg = argv_next(&ac, &av);
1994 if (!arg || *arg == '\0')
1995 fatal("%s line %d: %s missing argument.",
1996 filename, linenum, keyword);
1997 if ((n = sscanf(arg, "%d:%d:%d",
1998 &options->max_startups_begin,
1999 &options->max_startups_rate,
2000 &options->max_startups)) == 3) {
2001 if (options->max_startups_begin >
2002 options->max_startups ||
2003 options->max_startups_rate > 100 ||
2004 options->max_startups_rate < 1)
2005 fatal("%s line %d: Invalid %s spec.",
2006 filename, linenum, keyword);
2007 } else if (n != 1)
2008 fatal("%s line %d: Invalid %s spec.",
2009 filename, linenum, keyword);
2010 else
2011 options->max_startups = options->max_startups_begin;
2012 if (options->max_startups <= 0 ||
2013 options->max_startups_begin <= 0)
2014 fatal("%s line %d: Invalid %s spec.",
2015 filename, linenum, keyword);
2016 break;
2018 case sPerSourceNetBlockSize:
2019 arg = argv_next(&ac, &av);
2020 if (!arg || *arg == '\0')
2021 fatal("%s line %d: %s missing argument.",
2022 filename, linenum, keyword);
2023 switch (n = sscanf(arg, "%d:%d", &value, &value2)) {
2024 case 2:
2025 if (value2 < 0 || value2 > 128)
2026 n = -1;
2027 /* FALLTHROUGH */
2028 case 1:
2029 if (value < 0 || value > 32)
2030 n = -1;
2032 if (n != 1 && n != 2)
2033 fatal("%s line %d: Invalid %s spec.",
2034 filename, linenum, keyword);
2035 if (*activep) {
2036 options->per_source_masklen_ipv4 = value;
2037 options->per_source_masklen_ipv6 = value2;
2039 break;
2041 case sPerSourceMaxStartups:
2042 arg = argv_next(&ac, &av);
2043 if (!arg || *arg == '\0')
2044 fatal("%s line %d: %s missing argument.",
2045 filename, linenum, keyword);
2046 if (strcmp(arg, "none") == 0) { /* no limit */
2047 value = INT_MAX;
2048 } else {
2049 if ((errstr = atoi_err(arg, &value)) != NULL)
2050 fatal("%s line %d: %s integer value %s.",
2051 filename, linenum, keyword, errstr);
2053 if (*activep && options->per_source_max_startups == -1)
2054 options->per_source_max_startups = value;
2055 break;
2057 case sPerSourcePenaltyExemptList:
2058 charptr = &options->per_source_penalty_exempt;
2059 arg = argv_next(&ac, &av);
2060 if (!arg || *arg == '\0')
2061 fatal("%s line %d: missing argument.",
2062 filename, linenum);
2063 if (addr_match_list(NULL, arg) != 0) {
2064 fatal("%s line %d: keyword %s "
2065 "invalid address argument.",
2066 filename, linenum, keyword);
2068 if (*activep && *charptr == NULL)
2069 *charptr = xstrdup(arg);
2070 break;
2072 case sPerSourcePenalties:
2073 while ((arg = argv_next(&ac, &av)) != NULL) {
2074 found = 1;
2075 value = -1;
2076 value2 = 0;
2077 p = NULL;
2078 /* Allow no/yes only in first position */
2079 if (strcasecmp(arg, "no") == 0 ||
2080 (value2 = (strcasecmp(arg, "yes") == 0))) {
2081 if (ac > 0) {
2082 fatal("%s line %d: keyword %s \"%s\" "
2083 "argument must appear alone.",
2084 filename, linenum, keyword, arg);
2086 if (*activep &&
2087 options->per_source_penalty.enabled == -1)
2088 options->per_source_penalty.enabled = value2;
2089 continue;
2090 } else if (strncmp(arg, "crash:", 6) == 0) {
2091 p = arg + 6;
2092 intptr = &options->per_source_penalty.penalty_crash;
2093 } else if (strncmp(arg, "authfail:", 9) == 0) {
2094 p = arg + 9;
2095 intptr = &options->per_source_penalty.penalty_authfail;
2096 } else if (strncmp(arg, "noauth:", 7) == 0) {
2097 p = arg + 7;
2098 intptr = &options->per_source_penalty.penalty_noauth;
2099 } else if (strncmp(arg, "grace-exceeded:", 15) == 0) {
2100 p = arg + 15;
2101 intptr = &options->per_source_penalty.penalty_grace;
2102 } else if (strncmp(arg, "refuseconnection:", 17) == 0) {
2103 p = arg + 17;
2104 intptr = &options->per_source_penalty.penalty_refuseconnection;
2105 } else if (strncmp(arg, "max:", 4) == 0) {
2106 p = arg + 4;
2107 intptr = &options->per_source_penalty.penalty_max;
2108 } else if (strncmp(arg, "min:", 4) == 0) {
2109 p = arg + 4;
2110 intptr = &options->per_source_penalty.penalty_min;
2111 } else if (strncmp(arg, "max-sources4:", 13) == 0) {
2112 intptr = &options->per_source_penalty.max_sources4;
2113 if ((errstr = atoi_err(arg+13, &value)) != NULL)
2114 fatal("%s line %d: %s value %s.",
2115 filename, linenum, keyword, errstr);
2116 } else if (strncmp(arg, "max-sources6:", 13) == 0) {
2117 intptr = &options->per_source_penalty.max_sources6;
2118 if ((errstr = atoi_err(arg+13, &value)) != NULL)
2119 fatal("%s line %d: %s value %s.",
2120 filename, linenum, keyword, errstr);
2121 } else if (strcmp(arg, "overflow:deny-all") == 0) {
2122 intptr = &options->per_source_penalty.overflow_mode;
2123 value = PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL;
2124 } else if (strcmp(arg, "overflow:permissive") == 0) {
2125 intptr = &options->per_source_penalty.overflow_mode;
2126 value = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE;
2127 } else if (strcmp(arg, "overflow6:deny-all") == 0) {
2128 intptr = &options->per_source_penalty.overflow_mode6;
2129 value = PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL;
2130 } else if (strcmp(arg, "overflow6:permissive") == 0) {
2131 intptr = &options->per_source_penalty.overflow_mode6;
2132 value = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE;
2133 } else {
2134 fatal("%s line %d: unsupported %s keyword %s",
2135 filename, linenum, keyword, arg);
2137 /* If no value was parsed above, assume it's a time */
2138 if (value == -1 && (value = convtime(p)) == -1) {
2139 fatal("%s line %d: invalid %s time value.",
2140 filename, linenum, keyword);
2142 if (*activep && *intptr == -1) {
2143 *intptr = value;
2144 /* any option implicitly enables penalties */
2145 options->per_source_penalty.enabled = 1;
2148 if (!found) {
2149 fatal("%s line %d: no %s specified",
2150 filename, linenum, keyword);
2152 break;
2154 case sMaxAuthTries:
2155 intptr = &options->max_authtries;
2156 goto parse_int;
2158 case sMaxSessions:
2159 intptr = &options->max_sessions;
2160 goto parse_int;
2162 case sBanner:
2163 charptr = &options->banner;
2164 goto parse_filename;
2167 * These options can contain %X options expanded at
2168 * connect time, so that you can specify paths like:
2170 * AuthorizedKeysFile /etc/ssh_keys/%u
2172 case sAuthorizedKeysFile:
2173 found = options->num_authkeys_files == 0;
2174 while ((arg = argv_next(&ac, &av)) != NULL) {
2175 if (*arg == '\0') {
2176 error("%s line %d: keyword %s empty argument",
2177 filename, linenum, keyword);
2178 goto out;
2180 arg2 = tilde_expand_filename(arg, getuid());
2181 opt_array_append(filename, linenum, keyword,
2182 &strs, &nstrs, arg2);
2183 free(arg2);
2185 if (nstrs == 0) {
2186 fatal("%s line %d: no %s specified",
2187 filename, linenum, keyword);
2189 if (found && *activep) {
2190 options->authorized_keys_files = strs;
2191 options->num_authkeys_files = nstrs;
2192 strs = NULL; /* transferred */
2193 nstrs = 0;
2195 break;
2197 case sAuthorizedPrincipalsFile:
2198 charptr = &options->authorized_principals_file;
2199 arg = argv_next(&ac, &av);
2200 if (!arg || *arg == '\0')
2201 fatal("%s line %d: %s missing argument.",
2202 filename, linenum, keyword);
2203 if (*activep && *charptr == NULL) {
2204 *charptr = tilde_expand_filename(arg, getuid());
2205 /* increase optional counter */
2206 if (intptr != NULL)
2207 *intptr = *intptr + 1;
2209 break;
2211 case sClientAliveInterval:
2212 intptr = &options->client_alive_interval;
2213 goto parse_time;
2215 case sClientAliveCountMax:
2216 intptr = &options->client_alive_count_max;
2217 goto parse_int;
2219 case sAcceptEnv:
2220 /* XXX appends to list; doesn't respect first-match-wins */
2221 while ((arg = argv_next(&ac, &av)) != NULL) {
2222 if (*arg == '\0' || strchr(arg, '=') != NULL)
2223 fatal("%s line %d: Invalid environment name.",
2224 filename, linenum);
2225 found = 1;
2226 if (!*activep)
2227 continue;
2228 opt_array_append(filename, linenum, keyword,
2229 &options->accept_env, &options->num_accept_env,
2230 arg);
2232 if (!found) {
2233 fatal("%s line %d: no %s specified",
2234 filename, linenum, keyword);
2236 break;
2238 case sSetEnv:
2239 found = options->num_setenv == 0;
2240 while ((arg = argv_next(&ac, &av)) != NULL) {
2241 if (*arg == '\0' || strchr(arg, '=') == NULL)
2242 fatal("%s line %d: Invalid environment.",
2243 filename, linenum);
2244 if (lookup_setenv_in_list(arg, strs, nstrs) != NULL) {
2245 debug2("%s line %d: ignoring duplicate env "
2246 "name \"%.64s\"", filename, linenum, arg);
2247 continue;
2249 opt_array_append(filename, linenum, keyword,
2250 &strs, &nstrs, arg);
2252 if (nstrs == 0) {
2253 fatal("%s line %d: no %s specified",
2254 filename, linenum, keyword);
2256 if (found && *activep) {
2257 options->setenv = strs;
2258 options->num_setenv = nstrs;
2259 strs = NULL; /* transferred */
2260 nstrs = 0;
2262 break;
2264 case sPermitTunnel:
2265 intptr = &options->permit_tun;
2266 arg = argv_next(&ac, &av);
2267 if (!arg || *arg == '\0')
2268 fatal("%s line %d: %s missing argument.",
2269 filename, linenum, keyword);
2270 value = -1;
2271 for (i = 0; tunmode_desc[i].val != -1; i++)
2272 if (strcmp(tunmode_desc[i].text, arg) == 0) {
2273 value = tunmode_desc[i].val;
2274 break;
2276 if (value == -1)
2277 fatal("%s line %d: bad %s argument %s",
2278 filename, linenum, keyword, arg);
2279 if (*activep && *intptr == -1)
2280 *intptr = value;
2281 break;
2283 case sInclude:
2284 if (cmdline) {
2285 fatal("Include directive not supported as a "
2286 "command-line option");
2288 value = 0;
2289 while ((arg2 = argv_next(&ac, &av)) != NULL) {
2290 if (*arg2 == '\0') {
2291 error("%s line %d: keyword %s empty argument",
2292 filename, linenum, keyword);
2293 goto out;
2295 value++;
2296 found = 0;
2297 if (*arg2 != '/' && *arg2 != '~') {
2298 xasprintf(&arg, "%s/%s", SSHDIR, arg2);
2299 } else
2300 arg = xstrdup(arg2);
2303 * Don't let included files clobber the containing
2304 * file's Match state.
2306 oactive = *activep;
2308 /* consult cache of include files */
2309 TAILQ_FOREACH(item, includes, entry) {
2310 if (strcmp(item->selector, arg) != 0)
2311 continue;
2312 if (item->filename != NULL) {
2313 parse_server_config_depth(options,
2314 item->filename, item->contents,
2315 includes, connectinfo,
2316 (*inc_flags & SSHCFG_MATCH_ONLY
2317 ? SSHCFG_MATCH_ONLY : (oactive
2318 ? 0 : SSHCFG_NEVERMATCH)),
2319 activep, depth + 1);
2321 found = 1;
2322 *activep = oactive;
2324 if (found != 0) {
2325 free(arg);
2326 continue;
2329 /* requested glob was not in cache */
2330 debug2("%s line %d: new include %s",
2331 filename, linenum, arg);
2332 if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
2333 if (r != GLOB_NOMATCH) {
2334 fatal("%s line %d: include \"%s\" glob "
2335 "failed", filename, linenum, arg);
2338 * If no entry matched then record a
2339 * placeholder to skip later glob calls.
2341 debug2("%s line %d: no match for %s",
2342 filename, linenum, arg);
2343 item = xcalloc(1, sizeof(*item));
2344 item->selector = strdup(arg);
2345 TAILQ_INSERT_TAIL(includes,
2346 item, entry);
2348 if (gbuf.gl_pathc > INT_MAX)
2349 fatal_f("too many glob results");
2350 for (n = 0; n < (int)gbuf.gl_pathc; n++) {
2351 debug2("%s line %d: including %s",
2352 filename, linenum, gbuf.gl_pathv[n]);
2353 item = xcalloc(1, sizeof(*item));
2354 item->selector = strdup(arg);
2355 item->filename = strdup(gbuf.gl_pathv[n]);
2356 if ((item->contents = sshbuf_new()) == NULL)
2357 fatal_f("sshbuf_new failed");
2358 load_server_config(item->filename,
2359 item->contents);
2360 parse_server_config_depth(options,
2361 item->filename, item->contents,
2362 includes, connectinfo,
2363 (*inc_flags & SSHCFG_MATCH_ONLY
2364 ? SSHCFG_MATCH_ONLY : (oactive
2365 ? 0 : SSHCFG_NEVERMATCH)),
2366 activep, depth + 1);
2367 *activep = oactive;
2368 TAILQ_INSERT_TAIL(includes, item, entry);
2370 globfree(&gbuf);
2371 free(arg);
2373 if (value == 0) {
2374 fatal("%s line %d: %s missing filename argument",
2375 filename, linenum, keyword);
2377 break;
2379 case sMatch:
2380 if (cmdline)
2381 fatal("Match directive not supported as a command-line "
2382 "option");
2383 value = match_cfg_line(str, &ac, &av, linenum,
2384 (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
2385 if (value < 0)
2386 fatal("%s line %d: Bad Match condition", filename,
2387 linenum);
2388 *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
2390 * The MATCH_ONLY flag is applicable only until the first
2391 * match block.
2393 *inc_flags &= ~SSHCFG_MATCH_ONLY;
2394 break;
2396 case sPermitListen:
2397 case sPermitOpen:
2398 if (opcode == sPermitListen) {
2399 uintptr = &options->num_permitted_listens;
2400 chararrayptr = &options->permitted_listens;
2401 } else {
2402 uintptr = &options->num_permitted_opens;
2403 chararrayptr = &options->permitted_opens;
2405 found = *uintptr == 0;
2406 while ((arg = argv_next(&ac, &av)) != NULL) {
2407 if (strcmp(arg, "any") == 0 ||
2408 strcmp(arg, "none") == 0) {
2409 if (nstrs != 0) {
2410 fatal("%s line %d: %s must appear "
2411 "alone on a %s line.",
2412 filename, linenum, arg, keyword);
2414 opt_array_append(filename, linenum, keyword,
2415 &strs, &nstrs, arg);
2416 continue;
2419 if (opcode == sPermitListen &&
2420 strchr(arg, ':') == NULL) {
2422 * Allow bare port number for PermitListen
2423 * to indicate a wildcard listen host.
2425 xasprintf(&arg2, "*:%s", arg);
2426 } else {
2427 arg2 = xstrdup(arg);
2428 p = hpdelim(&arg);
2429 if (p == NULL) {
2430 fatal("%s line %d: %s missing host",
2431 filename, linenum, keyword);
2433 p = cleanhostname(p);
2435 if (arg == NULL ||
2436 ((port = permitopen_port(arg)) < 0)) {
2437 fatal("%s line %d: %s bad port number",
2438 filename, linenum, keyword);
2440 opt_array_append(filename, linenum, keyword,
2441 &strs, &nstrs, arg2);
2442 free(arg2);
2444 if (nstrs == 0) {
2445 fatal("%s line %d: %s missing argument.",
2446 filename, linenum, keyword);
2448 if (found && *activep) {
2449 *chararrayptr = strs;
2450 *uintptr = nstrs;
2451 strs = NULL; /* transferred */
2452 nstrs = 0;
2454 break;
2456 case sForceCommand:
2457 if (str == NULL || *str == '\0')
2458 fatal("%s line %d: %s missing argument.",
2459 filename, linenum, keyword);
2460 len = strspn(str, WHITESPACE);
2461 if (*activep && options->adm_forced_command == NULL)
2462 options->adm_forced_command = xstrdup(str + len);
2463 argv_consume(&ac);
2464 break;
2466 case sChrootDirectory:
2467 charptr = &options->chroot_directory;
2469 arg = argv_next(&ac, &av);
2470 if (!arg || *arg == '\0')
2471 fatal("%s line %d: %s missing argument.",
2472 filename, linenum, keyword);
2473 if (*activep && *charptr == NULL)
2474 *charptr = xstrdup(arg);
2475 break;
2477 case sTrustedUserCAKeys:
2478 charptr = &options->trusted_user_ca_keys;
2479 goto parse_filename;
2481 case sRevokedKeys:
2482 charptr = &options->revoked_keys_file;
2483 goto parse_filename;
2485 case sSecurityKeyProvider:
2486 charptr = &options->sk_provider;
2487 arg = argv_next(&ac, &av);
2488 if (!arg || *arg == '\0')
2489 fatal("%s line %d: %s missing argument.",
2490 filename, linenum, keyword);
2491 if (*activep && *charptr == NULL) {
2492 *charptr = strcasecmp(arg, "internal") == 0 ?
2493 xstrdup(arg) : derelativise_path(arg);
2494 /* increase optional counter */
2495 if (intptr != NULL)
2496 *intptr = *intptr + 1;
2498 break;
2500 case sIPQoS:
2501 arg = argv_next(&ac, &av);
2502 if (!arg || *arg == '\0')
2503 fatal("%s line %d: %s missing argument.",
2504 filename, linenum, keyword);
2505 if ((value = parse_ipqos(arg)) == -1)
2506 fatal("%s line %d: Bad %s value: %s",
2507 filename, linenum, keyword, arg);
2508 arg = argv_next(&ac, &av);
2509 if (arg == NULL)
2510 value2 = value;
2511 else if ((value2 = parse_ipqos(arg)) == -1)
2512 fatal("%s line %d: Bad %s value: %s",
2513 filename, linenum, keyword, arg);
2514 if (*activep) {
2515 options->ip_qos_interactive = value;
2516 options->ip_qos_bulk = value2;
2518 break;
2520 case sVersionAddendum:
2521 if (str == NULL || *str == '\0')
2522 fatal("%s line %d: %s missing argument.",
2523 filename, linenum, keyword);
2524 len = strspn(str, WHITESPACE);
2525 if (strchr(str + len, '\r') != NULL) {
2526 fatal("%.200s line %d: Invalid %s argument",
2527 filename, linenum, keyword);
2529 if ((arg = strchr(line, '#')) != NULL) {
2530 *arg = '\0';
2531 rtrim(line);
2533 if (*activep && options->version_addendum == NULL) {
2534 if (strcasecmp(str + len, "none") == 0)
2535 options->version_addendum = xstrdup("");
2536 else
2537 options->version_addendum = xstrdup(str + len);
2539 argv_consume(&ac);
2540 break;
2542 case sAuthorizedKeysCommand:
2543 charptr = &options->authorized_keys_command;
2544 parse_command:
2545 len = strspn(str, WHITESPACE);
2546 if (str[len] != '/' && strcasecmp(str + len, "none") != 0) {
2547 fatal("%.200s line %d: %s must be an absolute path",
2548 filename, linenum, keyword);
2550 if (*activep && *charptr == NULL)
2551 *charptr = xstrdup(str + len);
2552 argv_consume(&ac);
2553 break;
2555 case sAuthorizedKeysCommandUser:
2556 charptr = &options->authorized_keys_command_user;
2557 parse_localuser:
2558 arg = argv_next(&ac, &av);
2559 if (!arg || *arg == '\0') {
2560 fatal("%s line %d: missing %s argument.",
2561 filename, linenum, keyword);
2563 if (*activep && *charptr == NULL)
2564 *charptr = xstrdup(arg);
2565 break;
2567 case sAuthorizedPrincipalsCommand:
2568 charptr = &options->authorized_principals_command;
2569 goto parse_command;
2571 case sAuthorizedPrincipalsCommandUser:
2572 charptr = &options->authorized_principals_command_user;
2573 goto parse_localuser;
2575 case sAuthenticationMethods:
2576 found = options->num_auth_methods == 0;
2577 value = 0; /* seen "any" pseudo-method */
2578 while ((arg = argv_next(&ac, &av)) != NULL) {
2579 if (strcmp(arg, "any") == 0) {
2580 if (nstrs > 0) {
2581 fatal("%s line %d: \"any\" must "
2582 "appear alone in %s",
2583 filename, linenum, keyword);
2585 value = 1;
2586 } else if (value) {
2587 fatal("%s line %d: \"any\" must appear "
2588 "alone in %s", filename, linenum, keyword);
2589 } else if (auth2_methods_valid(arg, 0) != 0) {
2590 fatal("%s line %d: invalid %s method list.",
2591 filename, linenum, keyword);
2593 opt_array_append(filename, linenum, keyword,
2594 &strs, &nstrs, arg);
2596 if (nstrs == 0) {
2597 fatal("%s line %d: no %s specified",
2598 filename, linenum, keyword);
2600 if (found && *activep) {
2601 options->auth_methods = strs;
2602 options->num_auth_methods = nstrs;
2603 strs = NULL; /* transferred */
2604 nstrs = 0;
2606 break;
2608 case sStreamLocalBindMask:
2609 arg = argv_next(&ac, &av);
2610 if (!arg || *arg == '\0')
2611 fatal("%s line %d: %s missing argument.",
2612 filename, linenum, keyword);
2613 /* Parse mode in octal format */
2614 value = strtol(arg, &p, 8);
2615 if (arg == p || value < 0 || value > 0777)
2616 fatal("%s line %d: Invalid %s.",
2617 filename, linenum, keyword);
2618 if (*activep)
2619 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2620 break;
2622 case sStreamLocalBindUnlink:
2623 intptr = &options->fwd_opts.streamlocal_bind_unlink;
2624 goto parse_flag;
2626 case sFingerprintHash:
2627 arg = argv_next(&ac, &av);
2628 if (!arg || *arg == '\0')
2629 fatal("%s line %d: %s missing argument.",
2630 filename, linenum, keyword);
2631 if ((value = ssh_digest_alg_by_name(arg)) == -1)
2632 fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
2633 filename, linenum, keyword, arg);
2634 if (*activep)
2635 options->fingerprint_hash = value;
2636 break;
2638 case sExposeAuthInfo:
2639 intptr = &options->expose_userauth_info;
2640 goto parse_flag;
2642 case sRDomain:
2643 #if !defined(__OpenBSD__) && !defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
2644 fatal("%s line %d: setting RDomain not supported on this "
2645 "platform.", filename, linenum);
2646 #endif
2647 charptr = &options->routing_domain;
2648 arg = argv_next(&ac, &av);
2649 if (!arg || *arg == '\0')
2650 fatal("%s line %d: %s missing argument.",
2651 filename, linenum, keyword);
2652 if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2653 !valid_rdomain(arg))
2654 fatal("%s line %d: invalid routing domain",
2655 filename, linenum);
2656 if (*activep && *charptr == NULL)
2657 *charptr = xstrdup(arg);
2658 break;
2660 case sRequiredRSASize:
2661 intptr = &options->required_rsa_size;
2662 goto parse_int;
2664 case sChannelTimeout:
2665 found = options->num_channel_timeouts == 0;
2666 while ((arg = argv_next(&ac, &av)) != NULL) {
2667 /* Allow "none" only in first position */
2668 if (strcasecmp(arg, "none") == 0) {
2669 if (nstrs > 0 || ac > 0) {
2670 error("%s line %d: keyword %s \"none\" "
2671 "argument must appear alone.",
2672 filename, linenum, keyword);
2673 goto out;
2675 } else if (parse_pattern_interval(arg,
2676 NULL, NULL) != 0) {
2677 fatal("%s line %d: invalid channel timeout %s",
2678 filename, linenum, arg);
2680 opt_array_append(filename, linenum, keyword,
2681 &strs, &nstrs, arg);
2683 if (nstrs == 0) {
2684 fatal("%s line %d: no %s specified",
2685 filename, linenum, keyword);
2687 if (found && *activep) {
2688 options->channel_timeouts = strs;
2689 options->num_channel_timeouts = nstrs;
2690 strs = NULL; /* transferred */
2691 nstrs = 0;
2693 break;
2695 case sUnusedConnectionTimeout:
2696 intptr = &options->unused_connection_timeout;
2697 /* peek at first arg for "none" so we can reuse parse_time */
2698 if (av[0] != NULL && strcasecmp(av[0], "none") == 0) {
2699 (void)argv_next(&ac, &av); /* consume arg */
2700 if (*activep)
2701 *intptr = 0;
2702 break;
2704 goto parse_time;
2706 case sSshdSessionPath:
2707 charptr = &options->sshd_session_path;
2708 goto parse_filename;
2710 case sSshdAuthPath:
2711 charptr = &options->sshd_auth_path;
2712 goto parse_filename;
2714 case sRefuseConnection:
2715 intptr = &options->refuse_connection;
2716 multistate_ptr = multistate_flag;
2717 goto parse_multistate;
2719 case sDeprecated:
2720 case sIgnore:
2721 case sUnsupported:
2722 do_log2(opcode == sIgnore ?
2723 SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2724 "%s line %d: %s option %s", filename, linenum,
2725 opcode == sUnsupported ? "Unsupported" : "Deprecated",
2726 keyword);
2727 argv_consume(&ac);
2728 break;
2730 default:
2731 fatal("%s line %d: Missing handler for opcode %s (%d)",
2732 filename, linenum, keyword, opcode);
2734 /* Check that there is no garbage at end of line. */
2735 if (ac > 0) {
2736 error("%.200s line %d: keyword %s extra arguments "
2737 "at end of line", filename, linenum, keyword);
2738 goto out;
2741 /* success */
2742 ret = 0;
2743 out:
2744 opt_array_free2(strs, NULL, nstrs);
2745 argv_free(oav, oac);
2746 return ret;
2750 process_server_config_line(ServerOptions *options, char *line,
2751 const char *filename, int linenum, int *activep,
2752 struct connection_info *connectinfo, struct include_list *includes)
2754 int inc_flags = 0;
2756 return process_server_config_line_depth(options, line, filename,
2757 linenum, activep, connectinfo, &inc_flags, 0, includes);
2761 /* Reads the server configuration file. */
2763 void
2764 load_server_config(const char *filename, struct sshbuf *conf)
2766 struct stat st;
2767 char *line = NULL, *cp;
2768 size_t linesize = 0;
2769 FILE *f;
2770 int r;
2772 debug2_f("filename %s", filename);
2773 if ((f = fopen(filename, "r")) == NULL) {
2774 perror(filename);
2775 exit(1);
2777 sshbuf_reset(conf);
2778 /* grow buffer, so realloc is avoided for large config files */
2779 if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
2780 (r = sshbuf_allocate(conf, st.st_size)) != 0)
2781 fatal_fr(r, "allocate");
2782 while (getline(&line, &linesize, f) != -1) {
2784 * Strip whitespace
2785 * NB - preserve newlines, they are needed to reproduce
2786 * line numbers later for error messages
2788 cp = line + strspn(line, " \t\r");
2789 if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2790 fatal_fr(r, "sshbuf_put");
2792 free(line);
2793 if ((r = sshbuf_put_u8(conf, 0)) != 0)
2794 fatal_fr(r, "sshbuf_put_u8");
2795 fclose(f);
2796 debug2_f("done config len = %zu", sshbuf_len(conf));
2799 void
2800 parse_server_match_config(ServerOptions *options,
2801 struct include_list *includes, struct connection_info *connectinfo)
2803 ServerOptions mo;
2805 initialize_server_options(&mo);
2806 parse_server_config(&mo, "reprocess config", cfg, includes,
2807 connectinfo, 0);
2808 copy_set_server_options(options, &mo, 0);
2811 int parse_server_match_testspec(struct connection_info *ci, char *spec)
2813 char *p;
2815 while ((p = strsep(&spec, ",")) && *p != '\0') {
2816 if (strncmp(p, "addr=", 5) == 0) {
2817 ci->address = xstrdup(p + 5);
2818 } else if (strncmp(p, "host=", 5) == 0) {
2819 ci->host = xstrdup(p + 5);
2820 } else if (strncmp(p, "user=", 5) == 0) {
2821 ci->user = xstrdup(p + 5);
2822 } else if (strncmp(p, "laddr=", 6) == 0) {
2823 ci->laddress = xstrdup(p + 6);
2824 } else if (strncmp(p, "rdomain=", 8) == 0) {
2825 ci->rdomain = xstrdup(p + 8);
2826 } else if (strncmp(p, "lport=", 6) == 0) {
2827 ci->lport = a2port(p + 6);
2828 if (ci->lport == -1) {
2829 fprintf(stderr, "Invalid port '%s' in test mode"
2830 " specification %s\n", p+6, p);
2831 return -1;
2833 } else if (strcmp(p, "invalid-user") == 0) {
2834 ci->user_invalid = 1;
2835 } else {
2836 fprintf(stderr, "Invalid test mode specification %s\n",
2838 return -1;
2841 return 0;
2844 void
2845 servconf_merge_subsystems(ServerOptions *dst, ServerOptions *src)
2847 u_int i, j, found;
2849 for (i = 0; i < src->num_subsystems; i++) {
2850 found = 0;
2851 for (j = 0; j < dst->num_subsystems; j++) {
2852 if (strcmp(src->subsystem_name[i],
2853 dst->subsystem_name[j]) == 0) {
2854 found = 1;
2855 break;
2858 if (found) {
2859 debug_f("override \"%s\"", dst->subsystem_name[j]);
2860 free(dst->subsystem_command[j]);
2861 free(dst->subsystem_args[j]);
2862 dst->subsystem_command[j] =
2863 xstrdup(src->subsystem_command[i]);
2864 dst->subsystem_args[j] =
2865 xstrdup(src->subsystem_args[i]);
2866 continue;
2868 debug_f("add \"%s\"", src->subsystem_name[i]);
2869 dst->subsystem_name = xrecallocarray(
2870 dst->subsystem_name, dst->num_subsystems,
2871 dst->num_subsystems + 1, sizeof(*dst->subsystem_name));
2872 dst->subsystem_command = xrecallocarray(
2873 dst->subsystem_command, dst->num_subsystems,
2874 dst->num_subsystems + 1, sizeof(*dst->subsystem_command));
2875 dst->subsystem_args = xrecallocarray(
2876 dst->subsystem_args, dst->num_subsystems,
2877 dst->num_subsystems + 1, sizeof(*dst->subsystem_args));
2878 j = dst->num_subsystems++;
2879 dst->subsystem_name[j] = xstrdup(src->subsystem_name[i]);
2880 dst->subsystem_command[j] = xstrdup(src->subsystem_command[i]);
2881 dst->subsystem_args[j] = xstrdup(src->subsystem_args[i]);
2886 * Copy any supported values that are set.
2888 * If the preauth flag is set, we do not bother copying the string or
2889 * array values that are not used pre-authentication, because any that we
2890 * do use must be explicitly sent in mm_getpwnamallow().
2892 void
2893 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2895 #define M_CP_INTOPT(n) do {\
2896 if (src->n != -1) \
2897 dst->n = src->n; \
2898 } while (0)
2900 M_CP_INTOPT(password_authentication);
2901 M_CP_INTOPT(gss_authentication);
2902 M_CP_INTOPT(pubkey_authentication);
2903 M_CP_INTOPT(pubkey_auth_options);
2904 M_CP_INTOPT(kerberos_authentication);
2905 M_CP_INTOPT(hostbased_authentication);
2906 M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2907 M_CP_INTOPT(kbd_interactive_authentication);
2908 M_CP_INTOPT(permit_root_login);
2909 M_CP_INTOPT(permit_empty_passwd);
2910 M_CP_INTOPT(ignore_rhosts);
2912 M_CP_INTOPT(allow_tcp_forwarding);
2913 M_CP_INTOPT(allow_streamlocal_forwarding);
2914 M_CP_INTOPT(allow_agent_forwarding);
2915 M_CP_INTOPT(disable_forwarding);
2916 M_CP_INTOPT(expose_userauth_info);
2917 M_CP_INTOPT(permit_tun);
2918 M_CP_INTOPT(fwd_opts.gateway_ports);
2919 M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2920 M_CP_INTOPT(x11_display_offset);
2921 M_CP_INTOPT(x11_forwarding);
2922 M_CP_INTOPT(x11_use_localhost);
2923 M_CP_INTOPT(permit_tty);
2924 M_CP_INTOPT(permit_user_rc);
2925 M_CP_INTOPT(max_sessions);
2926 M_CP_INTOPT(max_authtries);
2927 M_CP_INTOPT(client_alive_count_max);
2928 M_CP_INTOPT(client_alive_interval);
2929 M_CP_INTOPT(ip_qos_interactive);
2930 M_CP_INTOPT(ip_qos_bulk);
2931 M_CP_INTOPT(rekey_limit);
2932 M_CP_INTOPT(rekey_interval);
2933 M_CP_INTOPT(log_level);
2934 M_CP_INTOPT(required_rsa_size);
2935 M_CP_INTOPT(unused_connection_timeout);
2936 M_CP_INTOPT(refuse_connection);
2939 * The bind_mask is a mode_t that may be unsigned, so we can't use
2940 * M_CP_INTOPT - it does a signed comparison that causes compiler
2941 * warnings.
2943 if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2944 dst->fwd_opts.streamlocal_bind_mask =
2945 src->fwd_opts.streamlocal_bind_mask;
2948 /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2949 #define M_CP_STROPT(n) do {\
2950 if (src->n != NULL && dst->n != src->n) { \
2951 free(dst->n); \
2952 dst->n = src->n; \
2954 } while(0)
2955 #define M_CP_STRARRAYOPT(s, num_s) do {\
2956 u_int i; \
2957 if (src->num_s != 0) { \
2958 for (i = 0; i < dst->num_s; i++) \
2959 free(dst->s[i]); \
2960 free(dst->s); \
2961 dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2962 for (i = 0; i < src->num_s; i++) \
2963 dst->s[i] = xstrdup(src->s[i]); \
2964 dst->num_s = src->num_s; \
2966 } while(0)
2968 /* See comment in servconf.h */
2969 COPY_MATCH_STRING_OPTS();
2971 /* Arguments that accept '+...' need to be expanded */
2972 assemble_algorithms(dst);
2975 * The only things that should be below this point are string options
2976 * which are only used after authentication.
2978 if (preauth)
2979 return;
2981 /* These options may be "none" to clear a global setting */
2982 M_CP_STROPT(adm_forced_command);
2983 if (option_clear_or_none(dst->adm_forced_command)) {
2984 free(dst->adm_forced_command);
2985 dst->adm_forced_command = NULL;
2987 M_CP_STROPT(chroot_directory);
2988 if (option_clear_or_none(dst->chroot_directory)) {
2989 free(dst->chroot_directory);
2990 dst->chroot_directory = NULL;
2993 /* Subsystems require merging. */
2994 servconf_merge_subsystems(dst, src);
2997 #undef M_CP_INTOPT
2998 #undef M_CP_STROPT
2999 #undef M_CP_STRARRAYOPT
3001 #define SERVCONF_MAX_DEPTH 16
3002 static void
3003 parse_server_config_depth(ServerOptions *options, const char *filename,
3004 struct sshbuf *conf, struct include_list *includes,
3005 struct connection_info *connectinfo, int flags, int *activep, int depth)
3007 int linenum, bad_options = 0;
3008 char *cp, *obuf, *cbuf;
3010 if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
3011 fatal("Too many recursive configuration includes");
3013 debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
3014 (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
3016 if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
3017 fatal_f("sshbuf_dup_string failed");
3018 linenum = 1;
3019 while ((cp = strsep(&cbuf, "\n")) != NULL) {
3020 if (process_server_config_line_depth(options, cp,
3021 filename, linenum++, activep, connectinfo, &flags,
3022 depth, includes) != 0)
3023 bad_options++;
3025 free(obuf);
3026 if (bad_options > 0)
3027 fatal("%s: terminating, %d bad configuration options",
3028 filename, bad_options);
3031 void
3032 parse_server_config(ServerOptions *options, const char *filename,
3033 struct sshbuf *conf, struct include_list *includes,
3034 struct connection_info *connectinfo, int reexec)
3036 int active = connectinfo ? 0 : 1;
3037 parse_server_config_depth(options, filename, conf, includes,
3038 connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
3039 if (!reexec)
3040 process_queued_listen_addrs(options);
3043 static const char *
3044 fmt_multistate_int(int val, const struct multistate *m)
3046 u_int i;
3048 for (i = 0; m[i].key != NULL; i++) {
3049 if (m[i].value == val)
3050 return m[i].key;
3052 return "UNKNOWN";
3055 static const char *
3056 fmt_intarg(ServerOpCodes code, int val)
3058 if (val == -1)
3059 return "unset";
3060 switch (code) {
3061 case sAddressFamily:
3062 return fmt_multistate_int(val, multistate_addressfamily);
3063 case sPermitRootLogin:
3064 return fmt_multistate_int(val, multistate_permitrootlogin);
3065 case sGatewayPorts:
3066 return fmt_multistate_int(val, multistate_gatewayports);
3067 case sCompression:
3068 return fmt_multistate_int(val, multistate_compression);
3069 case sAllowTcpForwarding:
3070 return fmt_multistate_int(val, multistate_tcpfwd);
3071 case sAllowStreamLocalForwarding:
3072 return fmt_multistate_int(val, multistate_tcpfwd);
3073 case sIgnoreRhosts:
3074 return fmt_multistate_int(val, multistate_ignore_rhosts);
3075 case sFingerprintHash:
3076 return ssh_digest_alg_name(val);
3077 default:
3078 switch (val) {
3079 case 0:
3080 return "no";
3081 case 1:
3082 return "yes";
3083 default:
3084 return "UNKNOWN";
3089 static void
3090 dump_cfg_int(ServerOpCodes code, int val)
3092 if (code == sUnusedConnectionTimeout && val == 0) {
3093 printf("%s none\n", lookup_opcode_name(code));
3094 return;
3096 printf("%s %d\n", lookup_opcode_name(code), val);
3099 static void
3100 dump_cfg_oct(ServerOpCodes code, int val)
3102 printf("%s 0%o\n", lookup_opcode_name(code), val);
3105 static void
3106 dump_cfg_fmtint(ServerOpCodes code, int val)
3108 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
3111 static void
3112 dump_cfg_string(ServerOpCodes code, const char *val)
3114 printf("%s %s\n", lookup_opcode_name(code),
3115 val == NULL ? "none" : val);
3118 static void
3119 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
3121 u_int i;
3123 for (i = 0; i < count; i++)
3124 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
3127 static void
3128 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
3130 u_int i;
3132 switch (code) {
3133 case sAuthenticationMethods:
3134 case sChannelTimeout:
3135 break;
3136 default:
3137 if (count <= 0)
3138 return;
3139 break;
3142 printf("%s", lookup_opcode_name(code));
3143 for (i = 0; i < count; i++)
3144 printf(" %s", vals[i]);
3145 if (code == sAuthenticationMethods && count == 0)
3146 printf(" any");
3147 else if (code == sChannelTimeout && count == 0)
3148 printf(" none");
3149 printf("\n");
3152 static char *
3153 format_listen_addrs(struct listenaddr *la)
3155 int r;
3156 struct addrinfo *ai;
3157 char addr[NI_MAXHOST], port[NI_MAXSERV];
3158 char *laddr1 = xstrdup(""), *laddr2 = NULL;
3161 * ListenAddress must be after Port. add_one_listen_addr pushes
3162 * addresses onto a stack, so to maintain ordering we need to
3163 * print these in reverse order.
3165 for (ai = la->addrs; ai; ai = ai->ai_next) {
3166 if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
3167 sizeof(addr), port, sizeof(port),
3168 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
3169 error("getnameinfo: %.100s", ssh_gai_strerror(r));
3170 continue;
3172 laddr2 = laddr1;
3173 if (ai->ai_family == AF_INET6) {
3174 xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
3175 addr, port,
3176 la->rdomain == NULL ? "" : " rdomain ",
3177 la->rdomain == NULL ? "" : la->rdomain,
3178 laddr2);
3179 } else {
3180 xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
3181 addr, port,
3182 la->rdomain == NULL ? "" : " rdomain ",
3183 la->rdomain == NULL ? "" : la->rdomain,
3184 laddr2);
3186 free(laddr2);
3188 return laddr1;
3191 void
3192 dump_config(ServerOptions *o)
3194 char *s;
3195 u_int i;
3197 /* these are usually at the top of the config */
3198 for (i = 0; i < o->num_ports; i++)
3199 printf("port %d\n", o->ports[i]);
3200 dump_cfg_fmtint(sAddressFamily, o->address_family);
3202 for (i = 0; i < o->num_listen_addrs; i++) {
3203 s = format_listen_addrs(&o->listen_addrs[i]);
3204 printf("%s", s);
3205 free(s);
3208 /* integer arguments */
3209 #ifdef USE_PAM
3210 dump_cfg_fmtint(sUsePAM, o->use_pam);
3211 dump_cfg_string(sPAMServiceName, o->pam_service_name);
3212 #endif
3213 dump_cfg_int(sLoginGraceTime, o->login_grace_time);
3214 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
3215 dump_cfg_int(sMaxAuthTries, o->max_authtries);
3216 dump_cfg_int(sMaxSessions, o->max_sessions);
3217 dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
3218 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
3219 dump_cfg_int(sRequiredRSASize, o->required_rsa_size);
3220 dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
3221 dump_cfg_int(sUnusedConnectionTimeout, o->unused_connection_timeout);
3223 /* formatted integer arguments */
3224 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
3225 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
3226 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
3227 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
3228 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
3229 o->hostbased_uses_name_from_packet_only);
3230 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
3231 #ifdef KRB5
3232 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
3233 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
3234 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
3235 # ifdef USE_AFS
3236 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
3237 # endif
3238 #endif
3239 #ifdef GSSAPI
3240 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
3241 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
3242 #endif
3243 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
3244 dump_cfg_fmtint(sKbdInteractiveAuthentication,
3245 o->kbd_interactive_authentication);
3246 dump_cfg_fmtint(sPrintMotd, o->print_motd);
3247 #ifndef DISABLE_LASTLOG
3248 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
3249 #endif
3250 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
3251 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
3252 dump_cfg_fmtint(sPermitTTY, o->permit_tty);
3253 dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
3254 dump_cfg_fmtint(sStrictModes, o->strict_modes);
3255 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
3256 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
3257 dump_cfg_fmtint(sCompression, o->compression);
3258 dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
3259 dump_cfg_fmtint(sUseDNS, o->use_dns);
3260 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
3261 dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
3262 dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
3263 dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
3264 dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
3265 dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
3266 dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
3267 dump_cfg_fmtint(sRefuseConnection, o->refuse_connection);
3269 /* string arguments */
3270 dump_cfg_string(sPidFile, o->pid_file);
3271 dump_cfg_string(sModuliFile, o->moduli_file);
3272 dump_cfg_string(sXAuthLocation, o->xauth_location);
3273 dump_cfg_string(sCiphers, o->ciphers);
3274 dump_cfg_string(sMacs, o->macs);
3275 dump_cfg_string(sBanner, o->banner);
3276 dump_cfg_string(sForceCommand, o->adm_forced_command);
3277 dump_cfg_string(sChrootDirectory, o->chroot_directory);
3278 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
3279 dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
3280 dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
3281 dump_cfg_string(sAuthorizedPrincipalsFile,
3282 o->authorized_principals_file);
3283 dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
3284 ? "none" : o->version_addendum);
3285 dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
3286 dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
3287 dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
3288 dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
3289 dump_cfg_string(sHostKeyAgent, o->host_key_agent);
3290 dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
3291 dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
3292 dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
3293 dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
3294 dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
3295 #if defined(__OpenBSD__) || defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
3296 dump_cfg_string(sRDomain, o->routing_domain);
3297 #endif
3298 dump_cfg_string(sSshdSessionPath, o->sshd_session_path);
3299 dump_cfg_string(sSshdAuthPath, o->sshd_auth_path);
3300 dump_cfg_string(sPerSourcePenaltyExemptList, o->per_source_penalty_exempt);
3302 /* string arguments requiring a lookup */
3303 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
3304 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
3306 /* string array arguments */
3307 dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
3308 o->authorized_keys_files);
3309 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
3310 o->host_key_files);
3311 dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
3312 o->host_cert_files);
3313 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
3314 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
3315 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
3316 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
3317 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
3318 dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
3319 dump_cfg_strarray_oneline(sAuthenticationMethods,
3320 o->num_auth_methods, o->auth_methods);
3321 dump_cfg_strarray_oneline(sLogVerbose,
3322 o->num_log_verbose, o->log_verbose);
3323 dump_cfg_strarray_oneline(sChannelTimeout,
3324 o->num_channel_timeouts, o->channel_timeouts);
3326 /* other arguments */
3327 for (i = 0; i < o->num_subsystems; i++)
3328 printf("subsystem %s %s\n", o->subsystem_name[i],
3329 o->subsystem_args[i]);
3331 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
3332 o->max_startups_rate, o->max_startups);
3333 printf("persourcemaxstartups ");
3334 if (o->per_source_max_startups == INT_MAX)
3335 printf("none\n");
3336 else
3337 printf("%d\n", o->per_source_max_startups);
3338 printf("persourcenetblocksize %d:%d\n", o->per_source_masklen_ipv4,
3339 o->per_source_masklen_ipv6);
3341 s = NULL;
3342 for (i = 0; tunmode_desc[i].val != -1; i++) {
3343 if (tunmode_desc[i].val == o->permit_tun) {
3344 s = tunmode_desc[i].text;
3345 break;
3348 dump_cfg_string(sPermitTunnel, s);
3350 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
3351 printf("%s\n", iptos2str(o->ip_qos_bulk));
3353 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
3354 o->rekey_interval);
3356 printf("permitopen");
3357 if (o->num_permitted_opens == 0)
3358 printf(" any");
3359 else {
3360 for (i = 0; i < o->num_permitted_opens; i++)
3361 printf(" %s", o->permitted_opens[i]);
3363 printf("\n");
3364 printf("permitlisten");
3365 if (o->num_permitted_listens == 0)
3366 printf(" any");
3367 else {
3368 for (i = 0; i < o->num_permitted_listens; i++)
3369 printf(" %s", o->permitted_listens[i]);
3371 printf("\n");
3373 if (o->permit_user_env_allowlist == NULL) {
3374 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
3375 } else {
3376 printf("permituserenvironment %s\n",
3377 o->permit_user_env_allowlist);
3380 printf("pubkeyauthoptions");
3381 if (o->pubkey_auth_options == 0)
3382 printf(" none");
3383 if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
3384 printf(" touch-required");
3385 if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
3386 printf(" verify-required");
3387 printf("\n");
3389 if (o->per_source_penalty.enabled) {
3390 printf("persourcepenalties crash:%d authfail:%d noauth:%d "
3391 "grace-exceeded:%d refuseconnection:%d max:%d min:%d "
3392 "max-sources4:%d max-sources6:%d "
3393 "overflow:%s overflow6:%s\n",
3394 o->per_source_penalty.penalty_crash,
3395 o->per_source_penalty.penalty_authfail,
3396 o->per_source_penalty.penalty_noauth,
3397 o->per_source_penalty.penalty_grace,
3398 o->per_source_penalty.penalty_refuseconnection,
3399 o->per_source_penalty.penalty_max,
3400 o->per_source_penalty.penalty_min,
3401 o->per_source_penalty.max_sources4,
3402 o->per_source_penalty.max_sources6,
3403 o->per_source_penalty.overflow_mode ==
3404 PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL ?
3405 "deny-all" : "permissive",
3406 o->per_source_penalty.overflow_mode6 ==
3407 PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL ?
3408 "deny-all" : "permissive");
3409 } else
3410 printf("persourcepenalties no\n");