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