Bug Summary

File:src/usr.bin/ssh/sshd/../servconf.c
Warning:line 2231, column 10
Although the value stored to 'port' is used in the enclosing expression, the value is never actually read from 'port'

Annotated Source Code

Press '?' to see keyboard shortcuts

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