GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/ssh/sshd/../servconf.c Lines: 0 1266 0.0 %
Date: 2017-11-13 Branches: 0 1154 0.0 %

Line Branch Exec Source
1
2
/* $OpenBSD: servconf.c,v 1.320 2017/11/03 05:18:44 djm Exp $ */
3
/*
4
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5
 *                    All rights reserved
6
 *
7
 * As far as I am concerned, the code I have written for this software
8
 * can be used freely for any purpose.  Any derived versions of this
9
 * software must be clearly marked as such, and if the derived work is
10
 * incompatible with the protocol description in the RFC file, it must be
11
 * called by a name other than "ssh" or "Secure Shell".
12
 */
13
14
#include <sys/types.h>
15
#include <sys/socket.h>
16
#include <sys/queue.h>
17
#include <sys/sysctl.h>
18
19
#include <netinet/in.h>
20
#include <netinet/ip.h>
21
#include <net/route.h>
22
23
#include <ctype.h>
24
#include <netdb.h>
25
#include <pwd.h>
26
#include <stdio.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <signal.h>
30
#include <unistd.h>
31
#include <limits.h>
32
#include <stdarg.h>
33
#include <errno.h>
34
#include <util.h>
35
36
#include "xmalloc.h"
37
#include "ssh.h"
38
#include "log.h"
39
#include "buffer.h"
40
#include "misc.h"
41
#include "servconf.h"
42
#include "compat.h"
43
#include "pathnames.h"
44
#include "cipher.h"
45
#include "key.h"
46
#include "kex.h"
47
#include "mac.h"
48
#include "match.h"
49
#include "channels.h"
50
#include "groupaccess.h"
51
#include "canohost.h"
52
#include "packet.h"
53
#include "hostfile.h"
54
#include "auth.h"
55
#include "myproposal.h"
56
#include "digest.h"
57
58
static void add_listen_addr(ServerOptions *, const char *,
59
    const char *, int);
60
static void add_one_listen_addr(ServerOptions *, const char *,
61
    const char *, int);
62
63
/* Use of privilege separation or not */
64
extern int use_privsep;
65
extern Buffer cfg;
66
67
/* Initializes the server options to their default values. */
68
69
void
70
initialize_server_options(ServerOptions *options)
71
{
72
	memset(options, 0, sizeof(*options));
73
	options->num_ports = 0;
74
	options->ports_from_cmdline = 0;
75
	options->queued_listen_addrs = NULL;
76
	options->num_queued_listens = 0;
77
	options->listen_addrs = NULL;
78
	options->num_listen_addrs = 0;
79
	options->address_family = -1;
80
	options->routing_domain = NULL;
81
	options->num_host_key_files = 0;
82
	options->num_host_cert_files = 0;
83
	options->host_key_agent = NULL;
84
	options->pid_file = NULL;
85
	options->login_grace_time = -1;
86
	options->permit_root_login = PERMIT_NOT_SET;
87
	options->ignore_rhosts = -1;
88
	options->ignore_user_known_hosts = -1;
89
	options->print_motd = -1;
90
	options->print_lastlog = -1;
91
	options->x11_forwarding = -1;
92
	options->x11_display_offset = -1;
93
	options->x11_use_localhost = -1;
94
	options->permit_tty = -1;
95
	options->permit_user_rc = -1;
96
	options->xauth_location = NULL;
97
	options->strict_modes = -1;
98
	options->tcp_keep_alive = -1;
99
	options->log_facility = SYSLOG_FACILITY_NOT_SET;
100
	options->log_level = SYSLOG_LEVEL_NOT_SET;
101
	options->hostbased_authentication = -1;
102
	options->hostbased_uses_name_from_packet_only = -1;
103
	options->hostbased_key_types = NULL;
104
	options->hostkeyalgorithms = NULL;
105
	options->pubkey_authentication = -1;
106
	options->pubkey_key_types = NULL;
107
	options->kerberos_authentication = -1;
108
	options->kerberos_or_local_passwd = -1;
109
	options->kerberos_ticket_cleanup = -1;
110
	options->kerberos_get_afs_token = -1;
111
	options->gss_authentication=-1;
112
	options->gss_cleanup_creds = -1;
113
	options->gss_strict_acceptor = -1;
114
	options->password_authentication = -1;
115
	options->kbd_interactive_authentication = -1;
116
	options->challenge_response_authentication = -1;
117
	options->permit_empty_passwd = -1;
118
	options->permit_user_env = -1;
119
	options->compression = -1;
120
	options->rekey_limit = -1;
121
	options->rekey_interval = -1;
122
	options->allow_tcp_forwarding = -1;
123
	options->allow_streamlocal_forwarding = -1;
124
	options->allow_agent_forwarding = -1;
125
	options->num_allow_users = 0;
126
	options->num_deny_users = 0;
127
	options->num_allow_groups = 0;
128
	options->num_deny_groups = 0;
129
	options->ciphers = NULL;
130
	options->macs = NULL;
131
	options->kex_algorithms = NULL;
132
	options->fwd_opts.gateway_ports = -1;
133
	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
134
	options->fwd_opts.streamlocal_bind_unlink = -1;
135
	options->num_subsystems = 0;
136
	options->max_startups_begin = -1;
137
	options->max_startups_rate = -1;
138
	options->max_startups = -1;
139
	options->max_authtries = -1;
140
	options->max_sessions = -1;
141
	options->banner = NULL;
142
	options->use_dns = -1;
143
	options->client_alive_interval = -1;
144
	options->client_alive_count_max = -1;
145
	options->num_authkeys_files = 0;
146
	options->num_accept_env = 0;
147
	options->permit_tun = -1;
148
	options->permitted_opens = NULL;
149
	options->adm_forced_command = NULL;
150
	options->chroot_directory = NULL;
151
	options->authorized_keys_command = NULL;
152
	options->authorized_keys_command_user = NULL;
153
	options->revoked_keys_file = NULL;
154
	options->trusted_user_ca_keys = NULL;
155
	options->authorized_principals_file = NULL;
156
	options->authorized_principals_command = NULL;
157
	options->authorized_principals_command_user = NULL;
158
	options->ip_qos_interactive = -1;
159
	options->ip_qos_bulk = -1;
160
	options->version_addendum = NULL;
161
	options->fingerprint_hash = -1;
162
	options->disable_forwarding = -1;
163
	options->expose_userauth_info = -1;
164
}
165
166
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
167
static int
168
option_clear_or_none(const char *o)
169
{
170
	return o == NULL || strcasecmp(o, "none") == 0;
171
}
172
173
static void
174
assemble_algorithms(ServerOptions *o)
175
{
176
	if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 ||
177
	    kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 ||
178
	    kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 ||
179
	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
180
	    &o->hostkeyalgorithms) != 0 ||
181
	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
182
	    &o->hostbased_key_types) != 0 ||
183
	    kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0)
184
		fatal("kex_assemble_names failed");
185
}
186
187
static void
188
array_append(const char *file, const int line, const char *directive,
189
    char ***array, u_int *lp, const char *s)
190
{
191
192
	if (*lp >= INT_MAX)
193
		fatal("%s line %d: Too many %s entries", file, line, directive);
194
195
	*array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
196
	(*array)[*lp] = xstrdup(s);
197
	(*lp)++;
198
}
199
200
void
201
servconf_add_hostkey(const char *file, const int line,
202
    ServerOptions *options, const char *path)
203
{
204
	char *apath = derelativise_path(path);
205
206
	array_append(file, line, "HostKey",
207
	    &options->host_key_files, &options->num_host_key_files, apath);
208
	free(apath);
209
}
210
211
void
212
servconf_add_hostcert(const char *file, const int line,
213
    ServerOptions *options, const char *path)
214
{
215
	char *apath = derelativise_path(path);
216
217
	array_append(file, line, "HostCertificate",
218
	    &options->host_cert_files, &options->num_host_cert_files, apath);
219
	free(apath);
220
}
221
222
void
223
fill_default_server_options(ServerOptions *options)
224
{
225
	u_int i;
226
227
	if (options->num_host_key_files == 0) {
228
		/* fill default hostkeys */
229
		servconf_add_hostkey("[default]", 0, options,
230
		    _PATH_HOST_RSA_KEY_FILE);
231
		servconf_add_hostkey("[default]", 0, options,
232
		    _PATH_HOST_DSA_KEY_FILE);
233
		servconf_add_hostkey("[default]", 0, options,
234
		    _PATH_HOST_ECDSA_KEY_FILE);
235
		servconf_add_hostkey("[default]", 0, options,
236
		    _PATH_HOST_ED25519_KEY_FILE);
237
	}
238
	/* No certificates by default */
239
	if (options->num_ports == 0)
240
		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
241
	if (options->address_family == -1)
242
		options->address_family = AF_UNSPEC;
243
	if (options->listen_addrs == NULL)
244
		add_listen_addr(options, NULL, NULL, 0);
245
	if (options->pid_file == NULL)
246
		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
247
	if (options->login_grace_time == -1)
248
		options->login_grace_time = 120;
249
	if (options->permit_root_login == PERMIT_NOT_SET)
250
		options->permit_root_login = PERMIT_NO_PASSWD;
251
	if (options->ignore_rhosts == -1)
252
		options->ignore_rhosts = 1;
253
	if (options->ignore_user_known_hosts == -1)
254
		options->ignore_user_known_hosts = 0;
255
	if (options->print_motd == -1)
256
		options->print_motd = 1;
257
	if (options->print_lastlog == -1)
258
		options->print_lastlog = 1;
259
	if (options->x11_forwarding == -1)
260
		options->x11_forwarding = 0;
261
	if (options->x11_display_offset == -1)
262
		options->x11_display_offset = 10;
263
	if (options->x11_use_localhost == -1)
264
		options->x11_use_localhost = 1;
265
	if (options->xauth_location == NULL)
266
		options->xauth_location = xstrdup(_PATH_XAUTH);
267
	if (options->permit_tty == -1)
268
		options->permit_tty = 1;
269
	if (options->permit_user_rc == -1)
270
		options->permit_user_rc = 1;
271
	if (options->strict_modes == -1)
272
		options->strict_modes = 1;
273
	if (options->tcp_keep_alive == -1)
274
		options->tcp_keep_alive = 1;
275
	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
276
		options->log_facility = SYSLOG_FACILITY_AUTH;
277
	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
278
		options->log_level = SYSLOG_LEVEL_INFO;
279
	if (options->hostbased_authentication == -1)
280
		options->hostbased_authentication = 0;
281
	if (options->hostbased_uses_name_from_packet_only == -1)
282
		options->hostbased_uses_name_from_packet_only = 0;
283
	if (options->pubkey_authentication == -1)
284
		options->pubkey_authentication = 1;
285
	if (options->kerberos_authentication == -1)
286
		options->kerberos_authentication = 0;
287
	if (options->kerberos_or_local_passwd == -1)
288
		options->kerberos_or_local_passwd = 1;
289
	if (options->kerberos_ticket_cleanup == -1)
290
		options->kerberos_ticket_cleanup = 1;
291
	if (options->kerberos_get_afs_token == -1)
292
		options->kerberos_get_afs_token = 0;
293
	if (options->gss_authentication == -1)
294
		options->gss_authentication = 0;
295
	if (options->gss_cleanup_creds == -1)
296
		options->gss_cleanup_creds = 1;
297
	if (options->gss_strict_acceptor == -1)
298
		options->gss_strict_acceptor = 1;
299
	if (options->password_authentication == -1)
300
		options->password_authentication = 1;
301
	if (options->kbd_interactive_authentication == -1)
302
		options->kbd_interactive_authentication = 0;
303
	if (options->challenge_response_authentication == -1)
304
		options->challenge_response_authentication = 1;
305
	if (options->permit_empty_passwd == -1)
306
		options->permit_empty_passwd = 0;
307
	if (options->permit_user_env == -1)
308
		options->permit_user_env = 0;
309
	if (options->compression == -1)
310
		options->compression = COMP_DELAYED;
311
	if (options->rekey_limit == -1)
312
		options->rekey_limit = 0;
313
	if (options->rekey_interval == -1)
314
		options->rekey_interval = 0;
315
	if (options->allow_tcp_forwarding == -1)
316
		options->allow_tcp_forwarding = FORWARD_ALLOW;
317
	if (options->allow_streamlocal_forwarding == -1)
318
		options->allow_streamlocal_forwarding = FORWARD_ALLOW;
319
	if (options->allow_agent_forwarding == -1)
320
		options->allow_agent_forwarding = 1;
321
	if (options->fwd_opts.gateway_ports == -1)
322
		options->fwd_opts.gateway_ports = 0;
323
	if (options->max_startups == -1)
324
		options->max_startups = 100;
325
	if (options->max_startups_rate == -1)
326
		options->max_startups_rate = 30;		/* 30% */
327
	if (options->max_startups_begin == -1)
328
		options->max_startups_begin = 10;
329
	if (options->max_authtries == -1)
330
		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
331
	if (options->max_sessions == -1)
332
		options->max_sessions = DEFAULT_SESSIONS_MAX;
333
	if (options->use_dns == -1)
334
		options->use_dns = 0;
335
	if (options->client_alive_interval == -1)
336
		options->client_alive_interval = 0;
337
	if (options->client_alive_count_max == -1)
338
		options->client_alive_count_max = 3;
339
	if (options->num_authkeys_files == 0) {
340
		array_append("[default]", 0, "AuthorizedKeysFiles",
341
		    &options->authorized_keys_files,
342
		    &options->num_authkeys_files,
343
		    _PATH_SSH_USER_PERMITTED_KEYS);
344
		array_append("[default]", 0, "AuthorizedKeysFiles",
345
		    &options->authorized_keys_files,
346
		    &options->num_authkeys_files,
347
		    _PATH_SSH_USER_PERMITTED_KEYS2);
348
	}
349
	if (options->permit_tun == -1)
350
		options->permit_tun = SSH_TUNMODE_NO;
351
	if (options->ip_qos_interactive == -1)
352
		options->ip_qos_interactive = IPTOS_LOWDELAY;
353
	if (options->ip_qos_bulk == -1)
354
		options->ip_qos_bulk = IPTOS_THROUGHPUT;
355
	if (options->version_addendum == NULL)
356
		options->version_addendum = xstrdup("");
357
	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
358
		options->fwd_opts.streamlocal_bind_mask = 0177;
359
	if (options->fwd_opts.streamlocal_bind_unlink == -1)
360
		options->fwd_opts.streamlocal_bind_unlink = 0;
361
	if (options->fingerprint_hash == -1)
362
		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
363
	if (options->disable_forwarding == -1)
364
		options->disable_forwarding = 0;
365
	if (options->expose_userauth_info == -1)
366
		options->expose_userauth_info = 0;
367
368
	assemble_algorithms(options);
369
370
	/* Turn privilege separation and sandboxing on by default */
371
	if (use_privsep == -1)
372
		use_privsep = PRIVSEP_ON;
373
374
#define CLEAR_ON_NONE(v) \
375
	do { \
376
		if (option_clear_or_none(v)) { \
377
			free(v); \
378
			v = NULL; \
379
		} \
380
	} while(0)
381
	CLEAR_ON_NONE(options->pid_file);
382
	CLEAR_ON_NONE(options->xauth_location);
383
	CLEAR_ON_NONE(options->banner);
384
	CLEAR_ON_NONE(options->trusted_user_ca_keys);
385
	CLEAR_ON_NONE(options->revoked_keys_file);
386
	CLEAR_ON_NONE(options->authorized_principals_file);
387
	CLEAR_ON_NONE(options->adm_forced_command);
388
	CLEAR_ON_NONE(options->chroot_directory);
389
	CLEAR_ON_NONE(options->routing_domain);
390
	for (i = 0; i < options->num_host_key_files; i++)
391
		CLEAR_ON_NONE(options->host_key_files[i]);
392
	for (i = 0; i < options->num_host_cert_files; i++)
393
		CLEAR_ON_NONE(options->host_cert_files[i]);
394
#undef CLEAR_ON_NONE
395
396
	/* Similar handling for AuthenticationMethods=any */
397
	if (options->num_auth_methods == 1 &&
398
	    strcmp(options->auth_methods[0], "any") == 0) {
399
		free(options->auth_methods[0]);
400
		options->auth_methods[0] = NULL;
401
		options->num_auth_methods = 0;
402
	}
403
404
}
405
406
/* Keyword tokens. */
407
typedef enum {
408
	sBadOption,		/* == unknown option */
409
	sPort, sHostKeyFile, sLoginGraceTime,
410
	sPermitRootLogin, sLogFacility, sLogLevel,
411
	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
412
	sKerberosGetAFSToken,
413
	sKerberosTgtPassing, sChallengeResponseAuthentication,
414
	sPasswordAuthentication, sKbdInteractiveAuthentication,
415
	sListenAddress, sAddressFamily,
416
	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
417
	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
418
	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
419
	sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
420
	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
421
	sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile,
422
	sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
423
	sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
424
	sBanner, sUseDNS, sHostbasedAuthentication,
425
	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
426
	sHostKeyAlgorithms,
427
	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
428
	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
429
	sAcceptEnv, sPermitTunnel,
430
	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
431
	sUsePrivilegeSeparation, sAllowAgentForwarding,
432
	sHostCertificate,
433
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
434
	sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
435
	sKexAlgorithms, sIPQoS, sVersionAddendum,
436
	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
437
	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
438
	sStreamLocalBindMask, sStreamLocalBindUnlink,
439
	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
440
	sExposeAuthInfo, sRDomain,
441
	sDeprecated, sIgnore, sUnsupported
442
} ServerOpCodes;
443
444
#define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
445
#define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
446
#define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
447
448
/* Textual representation of the tokens. */
449
static struct {
450
	const char *name;
451
	ServerOpCodes opcode;
452
	u_int flags;
453
} keywords[] = {
454
	{ "port", sPort, SSHCFG_GLOBAL },
455
	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
456
	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
457
	{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
458
	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
459
	{ "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
460
	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
461
	{ "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
462
	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
463
	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
464
	{ "loglevel", sLogLevel, SSHCFG_ALL },
465
	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
466
	{ "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
467
	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
468
	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
469
	{ "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL },
470
	{ "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
471
	{ "rsaauthentication", sDeprecated, SSHCFG_ALL },
472
	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
473
	{ "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL },
474
	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
475
#ifdef KRB5
476
	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
477
	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
478
	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
479
	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
480
#else
481
	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
482
	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
483
	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
484
	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
485
#endif
486
	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
487
	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
488
#ifdef GSSAPI
489
	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
490
	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
491
	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
492
#else
493
	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
494
	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
495
	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
496
#endif
497
	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
498
	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
499
	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
500
	{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
501
	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
502
	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
503
	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
504
	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
505
	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
506
	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
507
	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
508
	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
509
	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
510
	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
511
	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
512
	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
513
	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
514
	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
515
	{ "uselogin", sDeprecated, SSHCFG_GLOBAL },
516
	{ "compression", sCompression, SSHCFG_GLOBAL },
517
	{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
518
	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
519
	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
520
	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
521
	{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
522
	{ "allowusers", sAllowUsers, SSHCFG_ALL },
523
	{ "denyusers", sDenyUsers, SSHCFG_ALL },
524
	{ "allowgroups", sAllowGroups, SSHCFG_ALL },
525
	{ "denygroups", sDenyGroups, SSHCFG_ALL },
526
	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
527
	{ "macs", sMacs, SSHCFG_GLOBAL },
528
	{ "protocol", sIgnore, SSHCFG_GLOBAL },
529
	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
530
	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
531
	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
532
	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
533
	{ "maxsessions", sMaxSessions, SSHCFG_ALL },
534
	{ "banner", sBanner, SSHCFG_ALL },
535
	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
536
	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
537
	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
538
	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
539
	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
540
	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
541
	{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
542
	{ "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
543
	{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
544
	{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
545
	{ "permittty", sPermitTTY, SSHCFG_ALL },
546
	{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
547
	{ "match", sMatch, SSHCFG_ALL },
548
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
549
	{ "forcecommand", sForceCommand, SSHCFG_ALL },
550
	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
551
	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
552
	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
553
	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
554
	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
555
	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
556
	{ "ipqos", sIPQoS, SSHCFG_ALL },
557
	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
558
	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
559
	{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
560
	{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
561
	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
562
	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
563
	{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
564
	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
565
	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
566
	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
567
	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
568
	{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
569
	{ "rdomain", sRDomain, SSHCFG_ALL },
570
	{ NULL, sBadOption, 0 }
571
};
572
573
static struct {
574
	int val;
575
	char *text;
576
} tunmode_desc[] = {
577
	{ SSH_TUNMODE_NO, "no" },
578
	{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
579
	{ SSH_TUNMODE_ETHERNET, "ethernet" },
580
	{ SSH_TUNMODE_YES, "yes" },
581
	{ -1, NULL }
582
};
583
584
/*
585
 * Returns the number of the token pointed to by cp or sBadOption.
586
 */
587
588
static ServerOpCodes
589
parse_token(const char *cp, const char *filename,
590
	    int linenum, u_int *flags)
591
{
592
	u_int i;
593
594
	for (i = 0; keywords[i].name; i++)
595
		if (strcasecmp(cp, keywords[i].name) == 0) {
596
			*flags = keywords[i].flags;
597
			return keywords[i].opcode;
598
		}
599
600
	error("%s: line %d: Bad configuration option: %s",
601
	    filename, linenum, cp);
602
	return sBadOption;
603
}
604
605
char *
606
derelativise_path(const char *path)
607
{
608
	char *expanded, *ret, cwd[PATH_MAX];
609
610
	if (strcasecmp(path, "none") == 0)
611
		return xstrdup("none");
612
	expanded = tilde_expand_filename(path, getuid());
613
	if (*expanded == '/')
614
		return expanded;
615
	if (getcwd(cwd, sizeof(cwd)) == NULL)
616
		fatal("%s: getcwd: %s", __func__, strerror(errno));
617
	xasprintf(&ret, "%s/%s", cwd, expanded);
618
	free(expanded);
619
	return ret;
620
}
621
622
static void
623
add_listen_addr(ServerOptions *options, const char *addr,
624
    const char *rdomain, int port)
625
{
626
	u_int i;
627
628
	if (port > 0)
629
		add_one_listen_addr(options, addr, rdomain, port);
630
	else {
631
		for (i = 0; i < options->num_ports; i++) {
632
			add_one_listen_addr(options, addr, rdomain,
633
			    options->ports[i]);
634
		}
635
	}
636
}
637
638
static void
639
add_one_listen_addr(ServerOptions *options, const char *addr,
640
    const char *rdomain, int port)
641
{
642
	struct addrinfo hints, *ai, *aitop;
643
	char strport[NI_MAXSERV];
644
	int gaierr;
645
	u_int i;
646
647
	/* Find listen_addrs entry for this rdomain */
648
	for (i = 0; i < options->num_listen_addrs; i++) {
649
		if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
650
			break;
651
		if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
652
			continue;
653
		if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
654
			break;
655
	}
656
	if (i >= options->num_listen_addrs) {
657
		/* No entry for this rdomain; allocate one */
658
		if (i >= INT_MAX)
659
			fatal("%s: too many listen addresses", __func__);
660
		options->listen_addrs = xrecallocarray(options->listen_addrs,
661
		    options->num_listen_addrs, options->num_listen_addrs + 1,
662
		    sizeof(*options->listen_addrs));
663
		i = options->num_listen_addrs++;
664
		if (rdomain != NULL)
665
			options->listen_addrs[i].rdomain = xstrdup(rdomain);
666
	}
667
	/* options->listen_addrs[i] points to the addresses for this rdomain */
668
669
	memset(&hints, 0, sizeof(hints));
670
	hints.ai_family = options->address_family;
671
	hints.ai_socktype = SOCK_STREAM;
672
	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
673
	snprintf(strport, sizeof strport, "%d", port);
674
	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
675
		fatal("bad addr or host: %s (%s)",
676
		    addr ? addr : "<NULL>",
677
		    ssh_gai_strerror(gaierr));
678
	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
679
		;
680
	ai->ai_next = options->listen_addrs[i].addrs;
681
	options->listen_addrs[i].addrs = aitop;
682
}
683
684
/* Returns nonzero if the routing domain name is valid */
685
static int
686
valid_rdomain(const char *name)
687
{
688
	const char *errstr;
689
	long long num;
690
	struct rt_tableinfo info;
691
	int mib[6];
692
	size_t miblen = sizeof(mib);
693
694
	if (name == NULL)
695
		return 1;
696
697
	num = strtonum(name, 0, 255, &errstr);
698
	if (errstr != NULL)
699
		return 0;
700
701
	/* Check whether the table actually exists */
702
	memset(mib, 0, sizeof(mib));
703
	mib[0] = CTL_NET;
704
	mib[1] = PF_ROUTE;
705
	mib[4] = NET_RT_TABLE;
706
	mib[5] = (int)num;
707
	if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
708
		return 0;
709
710
	return 1;
711
}
712
713
/*
714
 * Queue a ListenAddress to be processed once we have all of the Ports
715
 * and AddressFamily options.
716
 */
717
static void
718
queue_listen_addr(ServerOptions *options, const char *addr,
719
    const char *rdomain, int port)
720
{
721
	struct queued_listenaddr *qla;
722
723
	options->queued_listen_addrs = xrecallocarray(
724
	    options->queued_listen_addrs,
725
	    options->num_queued_listens, options->num_queued_listens + 1,
726
	    sizeof(*options->queued_listen_addrs));
727
	qla = &options->queued_listen_addrs[options->num_queued_listens++];
728
	qla->addr = xstrdup(addr);
729
	qla->port = port;
730
	qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
731
}
732
733
/*
734
 * Process queued (text) ListenAddress entries.
735
 */
736
static void
737
process_queued_listen_addrs(ServerOptions *options)
738
{
739
	u_int i;
740
	struct queued_listenaddr *qla;
741
742
	if (options->num_ports == 0)
743
		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
744
	if (options->address_family == -1)
745
		options->address_family = AF_UNSPEC;
746
747
	for (i = 0; i < options->num_queued_listens; i++) {
748
		qla = &options->queued_listen_addrs[i];
749
		add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
750
		free(qla->addr);
751
		free(qla->rdomain);
752
	}
753
	free(options->queued_listen_addrs);
754
	options->queued_listen_addrs = NULL;
755
	options->num_queued_listens = 0;
756
}
757
758
/*
759
 * Inform channels layer of permitopen options from configuration.
760
 */
761
void
762
process_permitopen(struct ssh *ssh, ServerOptions *options)
763
{
764
	u_int i;
765
	int port;
766
	char *host, *arg, *oarg;
767
768
	channel_clear_adm_permitted_opens(ssh);
769
	if (options->num_permitted_opens == 0)
770
		return; /* permit any */
771
772
	/* handle keywords: "any" / "none" */
773
	if (options->num_permitted_opens == 1 &&
774
	    strcmp(options->permitted_opens[0], "any") == 0)
775
		return;
776
	if (options->num_permitted_opens == 1 &&
777
	    strcmp(options->permitted_opens[0], "none") == 0) {
778
		channel_disable_adm_local_opens(ssh);
779
		return;
780
	}
781
	/* Otherwise treat it as a list of permitted host:port */
782
	for (i = 0; i < options->num_permitted_opens; i++) {
783
		oarg = arg = xstrdup(options->permitted_opens[i]);
784
		host = hpdelim(&arg);
785
		if (host == NULL)
786
			fatal("%s: missing host in PermitOpen", __func__);
787
		host = cleanhostname(host);
788
		if (arg == NULL || ((port = permitopen_port(arg)) < 0))
789
			fatal("%s: bad port number in PermitOpen", __func__);
790
		/* Send it to channels layer */
791
		channel_add_adm_permitted_opens(ssh, host, port);
792
		free(oarg);
793
	}
794
}
795
796
struct connection_info *
797
get_connection_info(int populate, int use_dns)
798
{
799
	struct ssh *ssh = active_state; /* XXX */
800
	static struct connection_info ci;
801
802
	if (!populate)
803
		return &ci;
804
	ci.host = auth_get_canonical_hostname(ssh, use_dns);
805
	ci.address = ssh_remote_ipaddr(ssh);
806
	ci.laddress = ssh_local_ipaddr(ssh);
807
	ci.lport = ssh_local_port(ssh);
808
	ci.rdomain = ssh_packet_rdomain_in(ssh);
809
	return &ci;
810
}
811
812
/*
813
 * The strategy for the Match blocks is that the config file is parsed twice.
814
 *
815
 * The first time is at startup.  activep is initialized to 1 and the
816
 * directives in the global context are processed and acted on.  Hitting a
817
 * Match directive unsets activep and the directives inside the block are
818
 * checked for syntax only.
819
 *
820
 * The second time is after a connection has been established but before
821
 * authentication.  activep is initialized to 2 and global config directives
822
 * are ignored since they have already been processed.  If the criteria in a
823
 * Match block is met, activep is set and the subsequent directives
824
 * processed and actioned until EOF or another Match block unsets it.  Any
825
 * options set are copied into the main server config.
826
 *
827
 * Potential additions/improvements:
828
 *  - Add Match support for pre-kex directives, eg. Ciphers.
829
 *
830
 *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
831
 *	Match Address 192.168.0.*
832
 *		Tag trusted
833
 *	Match Group wheel
834
 *		Tag trusted
835
 *	Match Tag trusted
836
 *		AllowTcpForwarding yes
837
 *		GatewayPorts clientspecified
838
 *		[...]
839
 *
840
 *  - Add a PermittedChannelRequests directive
841
 *	Match Group shell
842
 *		PermittedChannelRequests session,forwarded-tcpip
843
 */
844
845
static int
846
match_cfg_line_group(const char *grps, int line, const char *user)
847
{
848
	int result = 0;
849
	struct passwd *pw;
850
851
	if (user == NULL)
852
		goto out;
853
854
	if ((pw = getpwnam(user)) == NULL) {
855
		debug("Can't match group at line %d because user %.100s does "
856
		    "not exist", line, user);
857
	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
858
		debug("Can't Match group because user %.100s not in any group "
859
		    "at line %d", user, line);
860
	} else if (ga_match_pattern_list(grps) != 1) {
861
		debug("user %.100s does not match group list %.100s at line %d",
862
		    user, grps, line);
863
	} else {
864
		debug("user %.100s matched group list %.100s at line %d", user,
865
		    grps, line);
866
		result = 1;
867
	}
868
out:
869
	ga_free();
870
	return result;
871
}
872
873
static void
874
match_test_missing_fatal(const char *criteria, const char *attrib)
875
{
876
	fatal("'Match %s' in configuration but '%s' not in connection "
877
	    "test specification.", criteria, attrib);
878
}
879
880
/*
881
 * All of the attributes on a single Match line are ANDed together, so we need
882
 * to check every attribute and set the result to zero if any attribute does
883
 * not match.
884
 */
885
static int
886
match_cfg_line(char **condition, int line, struct connection_info *ci)
887
{
888
	int result = 1, attributes = 0, port;
889
	char *arg, *attrib, *cp = *condition;
890
891
	if (ci == NULL)
892
		debug3("checking syntax for 'Match %s'", cp);
893
	else
894
		debug3("checking match for '%s' user %s host %s addr %s "
895
		    "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
896
		    ci->host ? ci->host : "(null)",
897
		    ci->address ? ci->address : "(null)",
898
		    ci->laddress ? ci->laddress : "(null)", ci->lport);
899
900
	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
901
		attributes++;
902
		if (strcasecmp(attrib, "all") == 0) {
903
			if (attributes != 1 ||
904
			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
905
				error("'all' cannot be combined with other "
906
				    "Match attributes");
907
				return -1;
908
			}
909
			*condition = cp;
910
			return 1;
911
		}
912
		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
913
			error("Missing Match criteria for %s", attrib);
914
			return -1;
915
		}
916
		if (strcasecmp(attrib, "user") == 0) {
917
			if (ci == NULL) {
918
				result = 0;
919
				continue;
920
			}
921
			if (ci->user == NULL)
922
				match_test_missing_fatal("User", "user");
923
			if (match_pattern_list(ci->user, arg, 0) != 1)
924
				result = 0;
925
			else
926
				debug("user %.100s matched 'User %.100s' at "
927
				    "line %d", ci->user, arg, line);
928
		} else if (strcasecmp(attrib, "group") == 0) {
929
			if (ci == NULL) {
930
				result = 0;
931
				continue;
932
			}
933
			if (ci->user == NULL)
934
				match_test_missing_fatal("Group", "user");
935
			switch (match_cfg_line_group(arg, line, ci->user)) {
936
			case -1:
937
				return -1;
938
			case 0:
939
				result = 0;
940
			}
941
		} else if (strcasecmp(attrib, "host") == 0) {
942
			if (ci == NULL) {
943
				result = 0;
944
				continue;
945
			}
946
			if (ci->host == NULL)
947
				match_test_missing_fatal("Host", "host");
948
			if (match_hostname(ci->host, arg) != 1)
949
				result = 0;
950
			else
951
				debug("connection from %.100s matched 'Host "
952
				    "%.100s' at line %d", ci->host, arg, line);
953
		} else if (strcasecmp(attrib, "address") == 0) {
954
			if (ci == NULL) {
955
				result = 0;
956
				continue;
957
			}
958
			if (ci->address == NULL)
959
				match_test_missing_fatal("Address", "addr");
960
			switch (addr_match_list(ci->address, arg)) {
961
			case 1:
962
				debug("connection from %.100s matched 'Address "
963
				    "%.100s' at line %d", ci->address, arg, line);
964
				break;
965
			case 0:
966
			case -1:
967
				result = 0;
968
				break;
969
			case -2:
970
				return -1;
971
			}
972
		} else if (strcasecmp(attrib, "localaddress") == 0){
973
			if (ci == NULL) {
974
				result = 0;
975
				continue;
976
			}
977
			if (ci->laddress == NULL)
978
				match_test_missing_fatal("LocalAddress",
979
				    "laddr");
980
			switch (addr_match_list(ci->laddress, arg)) {
981
			case 1:
982
				debug("connection from %.100s matched "
983
				    "'LocalAddress %.100s' at line %d",
984
				    ci->laddress, arg, line);
985
				break;
986
			case 0:
987
			case -1:
988
				result = 0;
989
				break;
990
			case -2:
991
				return -1;
992
			}
993
		} else if (strcasecmp(attrib, "localport") == 0) {
994
			if ((port = a2port(arg)) == -1) {
995
				error("Invalid LocalPort '%s' on Match line",
996
				    arg);
997
				return -1;
998
			}
999
			if (ci == NULL) {
1000
				result = 0;
1001
				continue;
1002
			}
1003
			if (ci->lport == 0)
1004
				match_test_missing_fatal("LocalPort", "lport");
1005
			/* TODO support port lists */
1006
			if (port == ci->lport)
1007
				debug("connection from %.100s matched "
1008
				    "'LocalPort %d' at line %d",
1009
				    ci->laddress, port, line);
1010
			else
1011
				result = 0;
1012
		} else if (strcasecmp(attrib, "rdomain") == 0) {
1013
			if (ci == NULL || ci->rdomain == NULL) {
1014
				result = 0;
1015
				continue;
1016
			}
1017
			if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1018
				result = 0;
1019
			else
1020
				debug("user %.100s matched 'RDomain %.100s' at "
1021
				    "line %d", ci->rdomain, arg, line);
1022
		} else {
1023
			error("Unsupported Match attribute %s", attrib);
1024
			return -1;
1025
		}
1026
	}
1027
	if (attributes == 0) {
1028
		error("One or more attributes required for Match");
1029
		return -1;
1030
	}
1031
	if (ci != NULL)
1032
		debug3("match %sfound", result ? "" : "not ");
1033
	*condition = cp;
1034
	return result;
1035
}
1036
1037
#define WHITESPACE " \t\r\n"
1038
1039
/* Multistate option parsing */
1040
struct multistate {
1041
	char *key;
1042
	int value;
1043
};
1044
static const struct multistate multistate_flag[] = {
1045
	{ "yes",			1 },
1046
	{ "no",				0 },
1047
	{ NULL, -1 }
1048
};
1049
static const struct multistate multistate_addressfamily[] = {
1050
	{ "inet",			AF_INET },
1051
	{ "inet6",			AF_INET6 },
1052
	{ "any",			AF_UNSPEC },
1053
	{ NULL, -1 }
1054
};
1055
static const struct multistate multistate_permitrootlogin[] = {
1056
	{ "without-password",		PERMIT_NO_PASSWD },
1057
	{ "prohibit-password",		PERMIT_NO_PASSWD },
1058
	{ "forced-commands-only",	PERMIT_FORCED_ONLY },
1059
	{ "yes",			PERMIT_YES },
1060
	{ "no",				PERMIT_NO },
1061
	{ NULL, -1 }
1062
};
1063
static const struct multistate multistate_compression[] = {
1064
	{ "yes",			COMP_DELAYED },
1065
	{ "delayed",			COMP_DELAYED },
1066
	{ "no",				COMP_NONE },
1067
	{ NULL, -1 }
1068
};
1069
static const struct multistate multistate_gatewayports[] = {
1070
	{ "clientspecified",		2 },
1071
	{ "yes",			1 },
1072
	{ "no",				0 },
1073
	{ NULL, -1 }
1074
};
1075
static const struct multistate multistate_tcpfwd[] = {
1076
	{ "yes",			FORWARD_ALLOW },
1077
	{ "all",			FORWARD_ALLOW },
1078
	{ "no",				FORWARD_DENY },
1079
	{ "remote",			FORWARD_REMOTE },
1080
	{ "local",			FORWARD_LOCAL },
1081
	{ NULL, -1 }
1082
};
1083
1084
int
1085
process_server_config_line(ServerOptions *options, char *line,
1086
    const char *filename, int linenum, int *activep,
1087
    struct connection_info *connectinfo)
1088
{
1089
	char *cp, **charptr, *arg, *arg2, *p;
1090
	int cmdline = 0, *intptr, value, value2, n, port;
1091
	SyslogFacility *log_facility_ptr;
1092
	LogLevel *log_level_ptr;
1093
	ServerOpCodes opcode;
1094
	u_int i, flags = 0;
1095
	size_t len;
1096
	long long val64;
1097
	const struct multistate *multistate_ptr;
1098
1099
	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1100
	if ((len = strlen(line)) == 0)
1101
		return 0;
1102
	for (len--; len > 0; len--) {
1103
		if (strchr(WHITESPACE "\f", line[len]) == NULL)
1104
			break;
1105
		line[len] = '\0';
1106
	}
1107
1108
	cp = line;
1109
	if ((arg = strdelim(&cp)) == NULL)
1110
		return 0;
1111
	/* Ignore leading whitespace */
1112
	if (*arg == '\0')
1113
		arg = strdelim(&cp);
1114
	if (!arg || !*arg || *arg == '#')
1115
		return 0;
1116
	intptr = NULL;
1117
	charptr = NULL;
1118
	opcode = parse_token(arg, filename, linenum, &flags);
1119
1120
	if (activep == NULL) { /* We are processing a command line directive */
1121
		cmdline = 1;
1122
		activep = &cmdline;
1123
	}
1124
	if (*activep && opcode != sMatch)
1125
		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
1126
	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1127
		if (connectinfo == NULL) {
1128
			fatal("%s line %d: Directive '%s' is not allowed "
1129
			    "within a Match block", filename, linenum, arg);
1130
		} else { /* this is a directive we have already processed */
1131
			while (arg)
1132
				arg = strdelim(&cp);
1133
			return 0;
1134
		}
1135
	}
1136
1137
	switch (opcode) {
1138
	case sBadOption:
1139
		return -1;
1140
	case sPort:
1141
		/* ignore ports from configfile if cmdline specifies ports */
1142
		if (options->ports_from_cmdline)
1143
			return 0;
1144
		if (options->num_ports >= MAX_PORTS)
1145
			fatal("%s line %d: too many ports.",
1146
			    filename, linenum);
1147
		arg = strdelim(&cp);
1148
		if (!arg || *arg == '\0')
1149
			fatal("%s line %d: missing port number.",
1150
			    filename, linenum);
1151
		options->ports[options->num_ports++] = a2port(arg);
1152
		if (options->ports[options->num_ports-1] <= 0)
1153
			fatal("%s line %d: Badly formatted port number.",
1154
			    filename, linenum);
1155
		break;
1156
1157
	case sLoginGraceTime:
1158
		intptr = &options->login_grace_time;
1159
 parse_time:
1160
		arg = strdelim(&cp);
1161
		if (!arg || *arg == '\0')
1162
			fatal("%s line %d: missing time value.",
1163
			    filename, linenum);
1164
		if ((value = convtime(arg)) == -1)
1165
			fatal("%s line %d: invalid time value.",
1166
			    filename, linenum);
1167
		if (*activep && *intptr == -1)
1168
			*intptr = value;
1169
		break;
1170
1171
	case sListenAddress:
1172
		arg = strdelim(&cp);
1173
		if (arg == NULL || *arg == '\0')
1174
			fatal("%s line %d: missing address",
1175
			    filename, linenum);
1176
		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
1177
		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1178
		    && strchr(p+1, ':') != NULL) {
1179
			port = 0;
1180
			p = arg;
1181
		} else {
1182
			p = hpdelim(&arg);
1183
			if (p == NULL)
1184
				fatal("%s line %d: bad address:port usage",
1185
				    filename, linenum);
1186
			p = cleanhostname(p);
1187
			if (arg == NULL)
1188
				port = 0;
1189
			else if ((port = a2port(arg)) <= 0)
1190
				fatal("%s line %d: bad port number",
1191
				    filename, linenum);
1192
		}
1193
		/* Optional routing table */
1194
		arg2 = NULL;
1195
		if ((arg = strdelim(&cp)) != NULL) {
1196
			if (strcmp(arg, "rdomain") != 0 ||
1197
			    (arg2 = strdelim(&cp)) == NULL)
1198
				fatal("%s line %d: bad ListenAddress syntax",
1199
				    filename, linenum);
1200
			if (!valid_rdomain(arg2))
1201
				fatal("%s line %d: bad routing domain",
1202
				    filename, linenum);
1203
		}
1204
1205
		queue_listen_addr(options, p, arg2, port);
1206
1207
		break;
1208
1209
	case sAddressFamily:
1210
		intptr = &options->address_family;
1211
		multistate_ptr = multistate_addressfamily;
1212
 parse_multistate:
1213
		arg = strdelim(&cp);
1214
		if (!arg || *arg == '\0')
1215
			fatal("%s line %d: missing argument.",
1216
			    filename, linenum);
1217
		value = -1;
1218
		for (i = 0; multistate_ptr[i].key != NULL; i++) {
1219
			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1220
				value = multistate_ptr[i].value;
1221
				break;
1222
			}
1223
		}
1224
		if (value == -1)
1225
			fatal("%s line %d: unsupported option \"%s\".",
1226
			    filename, linenum, arg);
1227
		if (*activep && *intptr == -1)
1228
			*intptr = value;
1229
		break;
1230
1231
	case sHostKeyFile:
1232
		arg = strdelim(&cp);
1233
		if (!arg || *arg == '\0')
1234
			fatal("%s line %d: missing file name.",
1235
			    filename, linenum);
1236
		if (*activep)
1237
			servconf_add_hostkey(filename, linenum, options, arg);
1238
		break;
1239
1240
	case sHostKeyAgent:
1241
		charptr = &options->host_key_agent;
1242
		arg = strdelim(&cp);
1243
		if (!arg || *arg == '\0')
1244
			fatal("%s line %d: missing socket name.",
1245
			    filename, linenum);
1246
		if (*activep && *charptr == NULL)
1247
			*charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1248
			    xstrdup(arg) : derelativise_path(arg);
1249
		break;
1250
1251
	case sHostCertificate:
1252
		arg = strdelim(&cp);
1253
		if (!arg || *arg == '\0')
1254
			fatal("%s line %d: missing file name.",
1255
			    filename, linenum);
1256
		if (*activep)
1257
			servconf_add_hostcert(filename, linenum, options, arg);
1258
		break;
1259
1260
	case sPidFile:
1261
		charptr = &options->pid_file;
1262
 parse_filename:
1263
		arg = strdelim(&cp);
1264
		if (!arg || *arg == '\0')
1265
			fatal("%s line %d: missing file name.",
1266
			    filename, linenum);
1267
		if (*activep && *charptr == NULL) {
1268
			*charptr = derelativise_path(arg);
1269
			/* increase optional counter */
1270
			if (intptr != NULL)
1271
				*intptr = *intptr + 1;
1272
		}
1273
		break;
1274
1275
	case sPermitRootLogin:
1276
		intptr = &options->permit_root_login;
1277
		multistate_ptr = multistate_permitrootlogin;
1278
		goto parse_multistate;
1279
1280
	case sIgnoreRhosts:
1281
		intptr = &options->ignore_rhosts;
1282
 parse_flag:
1283
		multistate_ptr = multistate_flag;
1284
		goto parse_multistate;
1285
1286
	case sIgnoreUserKnownHosts:
1287
		intptr = &options->ignore_user_known_hosts;
1288
		goto parse_flag;
1289
1290
	case sHostbasedAuthentication:
1291
		intptr = &options->hostbased_authentication;
1292
		goto parse_flag;
1293
1294
	case sHostbasedUsesNameFromPacketOnly:
1295
		intptr = &options->hostbased_uses_name_from_packet_only;
1296
		goto parse_flag;
1297
1298
	case sHostbasedAcceptedKeyTypes:
1299
		charptr = &options->hostbased_key_types;
1300
 parse_keytypes:
1301
		arg = strdelim(&cp);
1302
		if (!arg || *arg == '\0')
1303
			fatal("%s line %d: Missing argument.",
1304
			    filename, linenum);
1305
		if (*arg != '-' &&
1306
		    !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1307
			fatal("%s line %d: Bad key types '%s'.",
1308
			    filename, linenum, arg ? arg : "<NONE>");
1309
		if (*activep && *charptr == NULL)
1310
			*charptr = xstrdup(arg);
1311
		break;
1312
1313
	case sHostKeyAlgorithms:
1314
		charptr = &options->hostkeyalgorithms;
1315
		goto parse_keytypes;
1316
1317
	case sPubkeyAuthentication:
1318
		intptr = &options->pubkey_authentication;
1319
		goto parse_flag;
1320
1321
	case sPubkeyAcceptedKeyTypes:
1322
		charptr = &options->pubkey_key_types;
1323
		goto parse_keytypes;
1324
1325
	case sKerberosAuthentication:
1326
		intptr = &options->kerberos_authentication;
1327
		goto parse_flag;
1328
1329
	case sKerberosOrLocalPasswd:
1330
		intptr = &options->kerberos_or_local_passwd;
1331
		goto parse_flag;
1332
1333
	case sKerberosTicketCleanup:
1334
		intptr = &options->kerberos_ticket_cleanup;
1335
		goto parse_flag;
1336
1337
	case sKerberosGetAFSToken:
1338
		intptr = &options->kerberos_get_afs_token;
1339
		goto parse_flag;
1340
1341
	case sGssAuthentication:
1342
		intptr = &options->gss_authentication;
1343
		goto parse_flag;
1344
1345
	case sGssCleanupCreds:
1346
		intptr = &options->gss_cleanup_creds;
1347
		goto parse_flag;
1348
1349
	case sGssStrictAcceptor:
1350
		intptr = &options->gss_strict_acceptor;
1351
		goto parse_flag;
1352
1353
	case sPasswordAuthentication:
1354
		intptr = &options->password_authentication;
1355
		goto parse_flag;
1356
1357
	case sKbdInteractiveAuthentication:
1358
		intptr = &options->kbd_interactive_authentication;
1359
		goto parse_flag;
1360
1361
	case sChallengeResponseAuthentication:
1362
		intptr = &options->challenge_response_authentication;
1363
		goto parse_flag;
1364
1365
	case sPrintMotd:
1366
		intptr = &options->print_motd;
1367
		goto parse_flag;
1368
1369
	case sPrintLastLog:
1370
		intptr = &options->print_lastlog;
1371
		goto parse_flag;
1372
1373
	case sX11Forwarding:
1374
		intptr = &options->x11_forwarding;
1375
		goto parse_flag;
1376
1377
	case sX11DisplayOffset:
1378
		intptr = &options->x11_display_offset;
1379
 parse_int:
1380
		arg = strdelim(&cp);
1381
		if (!arg || *arg == '\0')
1382
			fatal("%s line %d: missing integer value.",
1383
			    filename, linenum);
1384
		value = atoi(arg);
1385
		if (*activep && *intptr == -1)
1386
			*intptr = value;
1387
		break;
1388
1389
	case sX11UseLocalhost:
1390
		intptr = &options->x11_use_localhost;
1391
		goto parse_flag;
1392
1393
	case sXAuthLocation:
1394
		charptr = &options->xauth_location;
1395
		goto parse_filename;
1396
1397
	case sPermitTTY:
1398
		intptr = &options->permit_tty;
1399
		goto parse_flag;
1400
1401
	case sPermitUserRC:
1402
		intptr = &options->permit_user_rc;
1403
		goto parse_flag;
1404
1405
	case sStrictModes:
1406
		intptr = &options->strict_modes;
1407
		goto parse_flag;
1408
1409
	case sTCPKeepAlive:
1410
		intptr = &options->tcp_keep_alive;
1411
		goto parse_flag;
1412
1413
	case sEmptyPasswd:
1414
		intptr = &options->permit_empty_passwd;
1415
		goto parse_flag;
1416
1417
	case sPermitUserEnvironment:
1418
		intptr = &options->permit_user_env;
1419
		goto parse_flag;
1420
1421
	case sCompression:
1422
		intptr = &options->compression;
1423
		multistate_ptr = multistate_compression;
1424
		goto parse_multistate;
1425
1426
	case sRekeyLimit:
1427
		arg = strdelim(&cp);
1428
		if (!arg || *arg == '\0')
1429
			fatal("%.200s line %d: Missing argument.", filename,
1430
			    linenum);
1431
		if (strcmp(arg, "default") == 0) {
1432
			val64 = 0;
1433
		} else {
1434
			if (scan_scaled(arg, &val64) == -1)
1435
				fatal("%.200s line %d: Bad number '%s': %s",
1436
				    filename, linenum, arg, strerror(errno));
1437
			if (val64 != 0 && val64 < 16)
1438
				fatal("%.200s line %d: RekeyLimit too small",
1439
				    filename, linenum);
1440
		}
1441
		if (*activep && options->rekey_limit == -1)
1442
			options->rekey_limit = val64;
1443
		if (cp != NULL) { /* optional rekey interval present */
1444
			if (strcmp(cp, "none") == 0) {
1445
				(void)strdelim(&cp);	/* discard */
1446
				break;
1447
			}
1448
			intptr = &options->rekey_interval;
1449
			goto parse_time;
1450
		}
1451
		break;
1452
1453
	case sGatewayPorts:
1454
		intptr = &options->fwd_opts.gateway_ports;
1455
		multistate_ptr = multistate_gatewayports;
1456
		goto parse_multistate;
1457
1458
	case sUseDNS:
1459
		intptr = &options->use_dns;
1460
		goto parse_flag;
1461
1462
	case sLogFacility:
1463
		log_facility_ptr = &options->log_facility;
1464
		arg = strdelim(&cp);
1465
		value = log_facility_number(arg);
1466
		if (value == SYSLOG_FACILITY_NOT_SET)
1467
			fatal("%.200s line %d: unsupported log facility '%s'",
1468
			    filename, linenum, arg ? arg : "<NONE>");
1469
		if (*log_facility_ptr == -1)
1470
			*log_facility_ptr = (SyslogFacility) value;
1471
		break;
1472
1473
	case sLogLevel:
1474
		log_level_ptr = &options->log_level;
1475
		arg = strdelim(&cp);
1476
		value = log_level_number(arg);
1477
		if (value == SYSLOG_LEVEL_NOT_SET)
1478
			fatal("%.200s line %d: unsupported log level '%s'",
1479
			    filename, linenum, arg ? arg : "<NONE>");
1480
		if (*activep && *log_level_ptr == -1)
1481
			*log_level_ptr = (LogLevel) value;
1482
		break;
1483
1484
	case sAllowTcpForwarding:
1485
		intptr = &options->allow_tcp_forwarding;
1486
		multistate_ptr = multistate_tcpfwd;
1487
		goto parse_multistate;
1488
1489
	case sAllowStreamLocalForwarding:
1490
		intptr = &options->allow_streamlocal_forwarding;
1491
		multistate_ptr = multistate_tcpfwd;
1492
		goto parse_multistate;
1493
1494
	case sAllowAgentForwarding:
1495
		intptr = &options->allow_agent_forwarding;
1496
		goto parse_flag;
1497
1498
	case sDisableForwarding:
1499
		intptr = &options->disable_forwarding;
1500
		goto parse_flag;
1501
1502
	case sAllowUsers:
1503
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1504
			if (match_user(NULL, NULL, NULL, arg) == -1)
1505
				fatal("%s line %d: invalid AllowUsers pattern: "
1506
				    "\"%.100s\"", filename, linenum, arg);
1507
			if (!*activep)
1508
				continue;
1509
			array_append(filename, linenum, "AllowUsers",
1510
			    &options->allow_users, &options->num_allow_users,
1511
			    arg);
1512
		}
1513
		break;
1514
1515
	case sDenyUsers:
1516
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1517
			if (match_user(NULL, NULL, NULL, arg) == -1)
1518
				fatal("%s line %d: invalid DenyUsers pattern: "
1519
				    "\"%.100s\"", filename, linenum, arg);
1520
			if (!*activep)
1521
				continue;
1522
			array_append(filename, linenum, "DenyUsers",
1523
			    &options->deny_users, &options->num_deny_users,
1524
			    arg);
1525
		}
1526
		break;
1527
1528
	case sAllowGroups:
1529
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1530
			if (!*activep)
1531
				continue;
1532
			array_append(filename, linenum, "AllowGroups",
1533
			    &options->allow_groups, &options->num_allow_groups,
1534
			    arg);
1535
		}
1536
		break;
1537
1538
	case sDenyGroups:
1539
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1540
			if (!*activep)
1541
				continue;
1542
			array_append(filename, linenum, "DenyGroups",
1543
			    &options->deny_groups, &options->num_deny_groups,
1544
			    arg);
1545
		}
1546
		break;
1547
1548
	case sCiphers:
1549
		arg = strdelim(&cp);
1550
		if (!arg || *arg == '\0')
1551
			fatal("%s line %d: Missing argument.", filename, linenum);
1552
		if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1553
			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1554
			    filename, linenum, arg ? arg : "<NONE>");
1555
		if (options->ciphers == NULL)
1556
			options->ciphers = xstrdup(arg);
1557
		break;
1558
1559
	case sMacs:
1560
		arg = strdelim(&cp);
1561
		if (!arg || *arg == '\0')
1562
			fatal("%s line %d: Missing argument.", filename, linenum);
1563
		if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1564
			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1565
			    filename, linenum, arg ? arg : "<NONE>");
1566
		if (options->macs == NULL)
1567
			options->macs = xstrdup(arg);
1568
		break;
1569
1570
	case sKexAlgorithms:
1571
		arg = strdelim(&cp);
1572
		if (!arg || *arg == '\0')
1573
			fatal("%s line %d: Missing argument.",
1574
			    filename, linenum);
1575
		if (*arg != '-' &&
1576
		    !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1577
			fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1578
			    filename, linenum, arg ? arg : "<NONE>");
1579
		if (options->kex_algorithms == NULL)
1580
			options->kex_algorithms = xstrdup(arg);
1581
		break;
1582
1583
	case sSubsystem:
1584
		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1585
			fatal("%s line %d: too many subsystems defined.",
1586
			    filename, linenum);
1587
		}
1588
		arg = strdelim(&cp);
1589
		if (!arg || *arg == '\0')
1590
			fatal("%s line %d: Missing subsystem name.",
1591
			    filename, linenum);
1592
		if (!*activep) {
1593
			arg = strdelim(&cp);
1594
			break;
1595
		}
1596
		for (i = 0; i < options->num_subsystems; i++)
1597
			if (strcmp(arg, options->subsystem_name[i]) == 0)
1598
				fatal("%s line %d: Subsystem '%s' already defined.",
1599
				    filename, linenum, arg);
1600
		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1601
		arg = strdelim(&cp);
1602
		if (!arg || *arg == '\0')
1603
			fatal("%s line %d: Missing subsystem command.",
1604
			    filename, linenum);
1605
		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1606
1607
		/* Collect arguments (separate to executable) */
1608
		p = xstrdup(arg);
1609
		len = strlen(p) + 1;
1610
		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1611
			len += 1 + strlen(arg);
1612
			p = xreallocarray(p, 1, len);
1613
			strlcat(p, " ", len);
1614
			strlcat(p, arg, len);
1615
		}
1616
		options->subsystem_args[options->num_subsystems] = p;
1617
		options->num_subsystems++;
1618
		break;
1619
1620
	case sMaxStartups:
1621
		arg = strdelim(&cp);
1622
		if (!arg || *arg == '\0')
1623
			fatal("%s line %d: Missing MaxStartups spec.",
1624
			    filename, linenum);
1625
		if ((n = sscanf(arg, "%d:%d:%d",
1626
		    &options->max_startups_begin,
1627
		    &options->max_startups_rate,
1628
		    &options->max_startups)) == 3) {
1629
			if (options->max_startups_begin >
1630
			    options->max_startups ||
1631
			    options->max_startups_rate > 100 ||
1632
			    options->max_startups_rate < 1)
1633
				fatal("%s line %d: Illegal MaxStartups spec.",
1634
				    filename, linenum);
1635
		} else if (n != 1)
1636
			fatal("%s line %d: Illegal MaxStartups spec.",
1637
			    filename, linenum);
1638
		else
1639
			options->max_startups = options->max_startups_begin;
1640
		break;
1641
1642
	case sMaxAuthTries:
1643
		intptr = &options->max_authtries;
1644
		goto parse_int;
1645
1646
	case sMaxSessions:
1647
		intptr = &options->max_sessions;
1648
		goto parse_int;
1649
1650
	case sBanner:
1651
		charptr = &options->banner;
1652
		goto parse_filename;
1653
1654
	/*
1655
	 * These options can contain %X options expanded at
1656
	 * connect time, so that you can specify paths like:
1657
	 *
1658
	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1659
	 */
1660
	case sAuthorizedKeysFile:
1661
		if (*activep && options->num_authkeys_files == 0) {
1662
			while ((arg = strdelim(&cp)) && *arg != '\0') {
1663
				arg = tilde_expand_filename(arg, getuid());
1664
				array_append(filename, linenum,
1665
				    "AuthorizedKeysFile",
1666
				    &options->authorized_keys_files,
1667
				    &options->num_authkeys_files, arg);
1668
				free(arg);
1669
			}
1670
		}
1671
		return 0;
1672
1673
	case sAuthorizedPrincipalsFile:
1674
		charptr = &options->authorized_principals_file;
1675
		arg = strdelim(&cp);
1676
		if (!arg || *arg == '\0')
1677
			fatal("%s line %d: missing file name.",
1678
			    filename, linenum);
1679
		if (*activep && *charptr == NULL) {
1680
			*charptr = tilde_expand_filename(arg, getuid());
1681
			/* increase optional counter */
1682
			if (intptr != NULL)
1683
				*intptr = *intptr + 1;
1684
		}
1685
		break;
1686
1687
	case sClientAliveInterval:
1688
		intptr = &options->client_alive_interval;
1689
		goto parse_time;
1690
1691
	case sClientAliveCountMax:
1692
		intptr = &options->client_alive_count_max;
1693
		goto parse_int;
1694
1695
	case sAcceptEnv:
1696
		while ((arg = strdelim(&cp)) && *arg != '\0') {
1697
			if (strchr(arg, '=') != NULL)
1698
				fatal("%s line %d: Invalid environment name.",
1699
				    filename, linenum);
1700
			if (!*activep)
1701
				continue;
1702
			array_append(filename, linenum, "AcceptEnv",
1703
			    &options->accept_env, &options->num_accept_env,
1704
			    arg);
1705
		}
1706
		break;
1707
1708
	case sPermitTunnel:
1709
		intptr = &options->permit_tun;
1710
		arg = strdelim(&cp);
1711
		if (!arg || *arg == '\0')
1712
			fatal("%s line %d: Missing yes/point-to-point/"
1713
			    "ethernet/no argument.", filename, linenum);
1714
		value = -1;
1715
		for (i = 0; tunmode_desc[i].val != -1; i++)
1716
			if (strcmp(tunmode_desc[i].text, arg) == 0) {
1717
				value = tunmode_desc[i].val;
1718
				break;
1719
			}
1720
		if (value == -1)
1721
			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1722
			    "no argument: %s", filename, linenum, arg);
1723
		if (*activep && *intptr == -1)
1724
			*intptr = value;
1725
		break;
1726
1727
	case sMatch:
1728
		if (cmdline)
1729
			fatal("Match directive not supported as a command-line "
1730
			   "option");
1731
		value = match_cfg_line(&cp, linenum, connectinfo);
1732
		if (value < 0)
1733
			fatal("%s line %d: Bad Match condition", filename,
1734
			    linenum);
1735
		*activep = value;
1736
		break;
1737
1738
	case sPermitOpen:
1739
		arg = strdelim(&cp);
1740
		if (!arg || *arg == '\0')
1741
			fatal("%s line %d: missing PermitOpen specification",
1742
			    filename, linenum);
1743
		value = options->num_permitted_opens;	/* modified later */
1744
		if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
1745
			if (*activep && value == 0) {
1746
				options->num_permitted_opens = 1;
1747
				options->permitted_opens = xcalloc(1,
1748
				    sizeof(*options->permitted_opens));
1749
				options->permitted_opens[0] = xstrdup(arg);
1750
			}
1751
			break;
1752
		}
1753
		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1754
			arg2 = xstrdup(arg);
1755
			p = hpdelim(&arg);
1756
			if (p == NULL)
1757
				fatal("%s line %d: missing host in PermitOpen",
1758
				    filename, linenum);
1759
			p = cleanhostname(p);
1760
			if (arg == NULL || ((port = permitopen_port(arg)) < 0))
1761
				fatal("%s line %d: bad port number in "
1762
				    "PermitOpen", filename, linenum);
1763
			if (*activep && value == 0) {
1764
				array_append(filename, linenum,
1765
				    "PermitOpen",
1766
				    &options->permitted_opens,
1767
				    &options->num_permitted_opens, arg2);
1768
			}
1769
			free(arg2);
1770
		}
1771
		break;
1772
1773
	case sForceCommand:
1774
		if (cp == NULL || *cp == '\0')
1775
			fatal("%.200s line %d: Missing argument.", filename,
1776
			    linenum);
1777
		len = strspn(cp, WHITESPACE);
1778
		if (*activep && options->adm_forced_command == NULL)
1779
			options->adm_forced_command = xstrdup(cp + len);
1780
		return 0;
1781
1782
	case sChrootDirectory:
1783
		charptr = &options->chroot_directory;
1784
1785
		arg = strdelim(&cp);
1786
		if (!arg || *arg == '\0')
1787
			fatal("%s line %d: missing file name.",
1788
			    filename, linenum);
1789
		if (*activep && *charptr == NULL)
1790
			*charptr = xstrdup(arg);
1791
		break;
1792
1793
	case sTrustedUserCAKeys:
1794
		charptr = &options->trusted_user_ca_keys;
1795
		goto parse_filename;
1796
1797
	case sRevokedKeys:
1798
		charptr = &options->revoked_keys_file;
1799
		goto parse_filename;
1800
1801
	case sIPQoS:
1802
		arg = strdelim(&cp);
1803
		if ((value = parse_ipqos(arg)) == -1)
1804
			fatal("%s line %d: Bad IPQoS value: %s",
1805
			    filename, linenum, arg);
1806
		arg = strdelim(&cp);
1807
		if (arg == NULL)
1808
			value2 = value;
1809
		else if ((value2 = parse_ipqos(arg)) == -1)
1810
			fatal("%s line %d: Bad IPQoS value: %s",
1811
			    filename, linenum, arg);
1812
		if (*activep) {
1813
			options->ip_qos_interactive = value;
1814
			options->ip_qos_bulk = value2;
1815
		}
1816
		break;
1817
1818
	case sVersionAddendum:
1819
		if (cp == NULL || *cp == '\0')
1820
			fatal("%.200s line %d: Missing argument.", filename,
1821
			    linenum);
1822
		len = strspn(cp, WHITESPACE);
1823
		if (*activep && options->version_addendum == NULL) {
1824
			if (strcasecmp(cp + len, "none") == 0)
1825
				options->version_addendum = xstrdup("");
1826
			else if (strchr(cp + len, '\r') != NULL)
1827
				fatal("%.200s line %d: Invalid argument",
1828
				    filename, linenum);
1829
			else
1830
				options->version_addendum = xstrdup(cp + len);
1831
		}
1832
		return 0;
1833
1834
	case sAuthorizedKeysCommand:
1835
		if (cp == NULL)
1836
			fatal("%.200s line %d: Missing argument.", filename,
1837
			    linenum);
1838
		len = strspn(cp, WHITESPACE);
1839
		if (*activep && options->authorized_keys_command == NULL) {
1840
			if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
1841
				fatal("%.200s line %d: AuthorizedKeysCommand "
1842
				    "must be an absolute path",
1843
				    filename, linenum);
1844
			options->authorized_keys_command = xstrdup(cp + len);
1845
		}
1846
		return 0;
1847
1848
	case sAuthorizedKeysCommandUser:
1849
		charptr = &options->authorized_keys_command_user;
1850
1851
		arg = strdelim(&cp);
1852
		if (!arg || *arg == '\0')
1853
			fatal("%s line %d: missing AuthorizedKeysCommandUser "
1854
			    "argument.", filename, linenum);
1855
		if (*activep && *charptr == NULL)
1856
			*charptr = xstrdup(arg);
1857
		break;
1858
1859
	case sAuthorizedPrincipalsCommand:
1860
		if (cp == NULL)
1861
			fatal("%.200s line %d: Missing argument.", filename,
1862
			    linenum);
1863
		len = strspn(cp, WHITESPACE);
1864
		if (*activep &&
1865
		    options->authorized_principals_command == NULL) {
1866
			if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
1867
				fatal("%.200s line %d: "
1868
				    "AuthorizedPrincipalsCommand must be "
1869
				    "an absolute path", filename, linenum);
1870
			options->authorized_principals_command =
1871
			    xstrdup(cp + len);
1872
		}
1873
		return 0;
1874
1875
	case sAuthorizedPrincipalsCommandUser:
1876
		charptr = &options->authorized_principals_command_user;
1877
1878
		arg = strdelim(&cp);
1879
		if (!arg || *arg == '\0')
1880
			fatal("%s line %d: missing "
1881
			    "AuthorizedPrincipalsCommandUser argument.",
1882
			    filename, linenum);
1883
		if (*activep && *charptr == NULL)
1884
			*charptr = xstrdup(arg);
1885
		break;
1886
1887
	case sAuthenticationMethods:
1888
		if (options->num_auth_methods == 0) {
1889
			value = 0; /* seen "any" pseudo-method */
1890
			value2 = 0; /* sucessfully parsed any method */
1891
			while ((arg = strdelim(&cp)) && *arg != '\0') {
1892
				if (strcmp(arg, "any") == 0) {
1893
					if (options->num_auth_methods > 0) {
1894
						fatal("%s line %d: \"any\" "
1895
						    "must appear alone in "
1896
						    "AuthenticationMethods",
1897
						    filename, linenum);
1898
					}
1899
					value = 1;
1900
				} else if (value) {
1901
					fatal("%s line %d: \"any\" must appear "
1902
					    "alone in AuthenticationMethods",
1903
					    filename, linenum);
1904
				} else if (auth2_methods_valid(arg, 0) != 0) {
1905
					fatal("%s line %d: invalid "
1906
					    "authentication method list.",
1907
					    filename, linenum);
1908
				}
1909
				value2 = 1;
1910
				if (!*activep)
1911
					continue;
1912
				array_append(filename, linenum,
1913
				    "AuthenticationMethods",
1914
				    &options->auth_methods,
1915
				    &options->num_auth_methods, arg);
1916
			}
1917
			if (value2 == 0) {
1918
				fatal("%s line %d: no AuthenticationMethods "
1919
				    "specified", filename, linenum);
1920
			}
1921
		}
1922
		return 0;
1923
1924
	case sStreamLocalBindMask:
1925
		arg = strdelim(&cp);
1926
		if (!arg || *arg == '\0')
1927
			fatal("%s line %d: missing StreamLocalBindMask "
1928
			    "argument.", filename, linenum);
1929
		/* Parse mode in octal format */
1930
		value = strtol(arg, &p, 8);
1931
		if (arg == p || value < 0 || value > 0777)
1932
			fatal("%s line %d: Bad mask.", filename, linenum);
1933
		if (*activep)
1934
			options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1935
		break;
1936
1937
	case sStreamLocalBindUnlink:
1938
		intptr = &options->fwd_opts.streamlocal_bind_unlink;
1939
		goto parse_flag;
1940
1941
	case sFingerprintHash:
1942
		arg = strdelim(&cp);
1943
		if (!arg || *arg == '\0')
1944
			fatal("%.200s line %d: Missing argument.",
1945
			    filename, linenum);
1946
		if ((value = ssh_digest_alg_by_name(arg)) == -1)
1947
			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1948
			    filename, linenum, arg);
1949
		if (*activep)
1950
			options->fingerprint_hash = value;
1951
		break;
1952
1953
	case sExposeAuthInfo:
1954
		intptr = &options->expose_userauth_info;
1955
		goto parse_flag;
1956
1957
	case sRDomain:
1958
		charptr = &options->routing_domain;
1959
		arg = strdelim(&cp);
1960
		if (!arg || *arg == '\0')
1961
			fatal("%.200s line %d: Missing argument.",
1962
			    filename, linenum);
1963
		if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
1964
		    !valid_rdomain(arg))
1965
			fatal("%s line %d: bad routing domain",
1966
			    filename, linenum);
1967
		if (*activep && *charptr == NULL)
1968
			*charptr = xstrdup(arg);
1969
1970
	case sDeprecated:
1971
	case sIgnore:
1972
	case sUnsupported:
1973
		do_log2(opcode == sIgnore ?
1974
		    SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
1975
		    "%s line %d: %s option %s", filename, linenum,
1976
		    opcode == sUnsupported ? "Unsupported" : "Deprecated", arg);
1977
		while (arg)
1978
		    arg = strdelim(&cp);
1979
		break;
1980
1981
	default:
1982
		fatal("%s line %d: Missing handler for opcode %s (%d)",
1983
		    filename, linenum, arg, opcode);
1984
	}
1985
	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1986
		fatal("%s line %d: garbage at end of line; \"%.200s\".",
1987
		    filename, linenum, arg);
1988
	return 0;
1989
}
1990
1991
/* Reads the server configuration file. */
1992
1993
void
1994
load_server_config(const char *filename, Buffer *conf)
1995
{
1996
	char line[4096], *cp;
1997
	FILE *f;
1998
	int lineno = 0;
1999
2000
	debug2("%s: filename %s", __func__, filename);
2001
	if ((f = fopen(filename, "r")) == NULL) {
2002
		perror(filename);
2003
		exit(1);
2004
	}
2005
	buffer_clear(conf);
2006
	while (fgets(line, sizeof(line), f)) {
2007
		lineno++;
2008
		if (strlen(line) == sizeof(line) - 1)
2009
			fatal("%s line %d too long", filename, lineno);
2010
		/*
2011
		 * Trim out comments and strip whitespace
2012
		 * NB - preserve newlines, they are needed to reproduce
2013
		 * line numbers later for error messages
2014
		 */
2015
		if ((cp = strchr(line, '#')) != NULL)
2016
			memcpy(cp, "\n", 2);
2017
		cp = line + strspn(line, " \t\r");
2018
2019
		buffer_append(conf, cp, strlen(cp));
2020
	}
2021
	buffer_append(conf, "\0", 1);
2022
	fclose(f);
2023
	debug2("%s: done config len = %d", __func__, buffer_len(conf));
2024
}
2025
2026
void
2027
parse_server_match_config(ServerOptions *options,
2028
   struct connection_info *connectinfo)
2029
{
2030
	ServerOptions mo;
2031
2032
	initialize_server_options(&mo);
2033
	parse_server_config(&mo, "reprocess config", &cfg, connectinfo);
2034
	copy_set_server_options(options, &mo, 0);
2035
}
2036
2037
int parse_server_match_testspec(struct connection_info *ci, char *spec)
2038
{
2039
	char *p;
2040
2041
	while ((p = strsep(&spec, ",")) && *p != '\0') {
2042
		if (strncmp(p, "addr=", 5) == 0) {
2043
			ci->address = xstrdup(p + 5);
2044
		} else if (strncmp(p, "host=", 5) == 0) {
2045
			ci->host = xstrdup(p + 5);
2046
		} else if (strncmp(p, "user=", 5) == 0) {
2047
			ci->user = xstrdup(p + 5);
2048
		} else if (strncmp(p, "laddr=", 6) == 0) {
2049
			ci->laddress = xstrdup(p + 6);
2050
		} else if (strncmp(p, "rdomain=", 8) == 0) {
2051
			ci->rdomain = xstrdup(p + 8);
2052
		} else if (strncmp(p, "lport=", 6) == 0) {
2053
			ci->lport = a2port(p + 6);
2054
			if (ci->lport == -1) {
2055
				fprintf(stderr, "Invalid port '%s' in test mode"
2056
				   " specification %s\n", p+6, p);
2057
				return -1;
2058
			}
2059
		} else {
2060
			fprintf(stderr, "Invalid test mode specification %s\n",
2061
			   p);
2062
			return -1;
2063
		}
2064
	}
2065
	return 0;
2066
}
2067
2068
/*
2069
 * Copy any supported values that are set.
2070
 *
2071
 * If the preauth flag is set, we do not bother copying the string or
2072
 * array values that are not used pre-authentication, because any that we
2073
 * do use must be explictly sent in mm_getpwnamallow().
2074
 */
2075
void
2076
copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2077
{
2078
#define M_CP_INTOPT(n) do {\
2079
	if (src->n != -1) \
2080
		dst->n = src->n; \
2081
} while (0)
2082
2083
	M_CP_INTOPT(password_authentication);
2084
	M_CP_INTOPT(gss_authentication);
2085
	M_CP_INTOPT(pubkey_authentication);
2086
	M_CP_INTOPT(kerberos_authentication);
2087
	M_CP_INTOPT(hostbased_authentication);
2088
	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2089
	M_CP_INTOPT(kbd_interactive_authentication);
2090
	M_CP_INTOPT(permit_root_login);
2091
	M_CP_INTOPT(permit_empty_passwd);
2092
2093
	M_CP_INTOPT(allow_tcp_forwarding);
2094
	M_CP_INTOPT(allow_streamlocal_forwarding);
2095
	M_CP_INTOPT(allow_agent_forwarding);
2096
	M_CP_INTOPT(disable_forwarding);
2097
	M_CP_INTOPT(expose_userauth_info);
2098
	M_CP_INTOPT(permit_tun);
2099
	M_CP_INTOPT(fwd_opts.gateway_ports);
2100
	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2101
	M_CP_INTOPT(x11_display_offset);
2102
	M_CP_INTOPT(x11_forwarding);
2103
	M_CP_INTOPT(x11_use_localhost);
2104
	M_CP_INTOPT(permit_tty);
2105
	M_CP_INTOPT(permit_user_rc);
2106
	M_CP_INTOPT(max_sessions);
2107
	M_CP_INTOPT(max_authtries);
2108
	M_CP_INTOPT(client_alive_count_max);
2109
	M_CP_INTOPT(client_alive_interval);
2110
	M_CP_INTOPT(ip_qos_interactive);
2111
	M_CP_INTOPT(ip_qos_bulk);
2112
	M_CP_INTOPT(rekey_limit);
2113
	M_CP_INTOPT(rekey_interval);
2114
	M_CP_INTOPT(log_level);
2115
2116
	/*
2117
	 * The bind_mask is a mode_t that may be unsigned, so we can't use
2118
	 * M_CP_INTOPT - it does a signed comparison that causes compiler
2119
	 * warnings.
2120
	 */
2121
	if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2122
		dst->fwd_opts.streamlocal_bind_mask =
2123
		    src->fwd_opts.streamlocal_bind_mask;
2124
	}
2125
2126
	/* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2127
#define M_CP_STROPT(n) do {\
2128
	if (src->n != NULL && dst->n != src->n) { \
2129
		free(dst->n); \
2130
		dst->n = src->n; \
2131
	} \
2132
} while(0)
2133
#define M_CP_STRARRAYOPT(s, num_s) do {\
2134
	u_int i; \
2135
	if (src->num_s != 0) { \
2136
		for (i = 0; i < dst->num_s; i++) \
2137
			free(dst->s[i]); \
2138
		free(dst->s); \
2139
		dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2140
		for (i = 0; i < src->num_s; i++) \
2141
			dst->s[i] = xstrdup(src->s[i]); \
2142
		dst->num_s = src->num_s; \
2143
	} \
2144
} while(0)
2145
2146
	/* See comment in servconf.h */
2147
	COPY_MATCH_STRING_OPTS();
2148
2149
	/* Arguments that accept '+...' need to be expanded */
2150
	assemble_algorithms(dst);
2151
2152
	/*
2153
	 * The only things that should be below this point are string options
2154
	 * which are only used after authentication.
2155
	 */
2156
	if (preauth)
2157
		return;
2158
2159
	/* These options may be "none" to clear a global setting */
2160
	M_CP_STROPT(adm_forced_command);
2161
	if (option_clear_or_none(dst->adm_forced_command)) {
2162
		free(dst->adm_forced_command);
2163
		dst->adm_forced_command = NULL;
2164
	}
2165
	M_CP_STROPT(chroot_directory);
2166
	if (option_clear_or_none(dst->chroot_directory)) {
2167
		free(dst->chroot_directory);
2168
		dst->chroot_directory = NULL;
2169
	}
2170
}
2171
2172
#undef M_CP_INTOPT
2173
#undef M_CP_STROPT
2174
#undef M_CP_STRARRAYOPT
2175
2176
void
2177
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
2178
    struct connection_info *connectinfo)
2179
{
2180
	int active, linenum, bad_options = 0;
2181
	char *cp, *obuf, *cbuf;
2182
2183
	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
2184
2185
	if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2186
		fatal("%s: sshbuf_dup_string failed", __func__);
2187
	active = connectinfo ? 0 : 1;
2188
	linenum = 1;
2189
	while ((cp = strsep(&cbuf, "\n")) != NULL) {
2190
		if (process_server_config_line(options, cp, filename,
2191
		    linenum++, &active, connectinfo) != 0)
2192
			bad_options++;
2193
	}
2194
	free(obuf);
2195
	if (bad_options > 0)
2196
		fatal("%s: terminating, %d bad configuration options",
2197
		    filename, bad_options);
2198
	process_queued_listen_addrs(options);
2199
}
2200
2201
static const char *
2202
fmt_multistate_int(int val, const struct multistate *m)
2203
{
2204
	u_int i;
2205
2206
	for (i = 0; m[i].key != NULL; i++) {
2207
		if (m[i].value == val)
2208
			return m[i].key;
2209
	}
2210
	return "UNKNOWN";
2211
}
2212
2213
static const char *
2214
fmt_intarg(ServerOpCodes code, int val)
2215
{
2216
	if (val == -1)
2217
		return "unset";
2218
	switch (code) {
2219
	case sAddressFamily:
2220
		return fmt_multistate_int(val, multistate_addressfamily);
2221
	case sPermitRootLogin:
2222
		return fmt_multistate_int(val, multistate_permitrootlogin);
2223
	case sGatewayPorts:
2224
		return fmt_multistate_int(val, multistate_gatewayports);
2225
	case sCompression:
2226
		return fmt_multistate_int(val, multistate_compression);
2227
	case sAllowTcpForwarding:
2228
		return fmt_multistate_int(val, multistate_tcpfwd);
2229
	case sAllowStreamLocalForwarding:
2230
		return fmt_multistate_int(val, multistate_tcpfwd);
2231
	case sFingerprintHash:
2232
		return ssh_digest_alg_name(val);
2233
	default:
2234
		switch (val) {
2235
		case 0:
2236
			return "no";
2237
		case 1:
2238
			return "yes";
2239
		default:
2240
			return "UNKNOWN";
2241
		}
2242
	}
2243
}
2244
2245
static const char *
2246
lookup_opcode_name(ServerOpCodes code)
2247
{
2248
	u_int i;
2249
2250
	for (i = 0; keywords[i].name != NULL; i++)
2251
		if (keywords[i].opcode == code)
2252
			return(keywords[i].name);
2253
	return "UNKNOWN";
2254
}
2255
2256
static void
2257
dump_cfg_int(ServerOpCodes code, int val)
2258
{
2259
	printf("%s %d\n", lookup_opcode_name(code), val);
2260
}
2261
2262
static void
2263
dump_cfg_oct(ServerOpCodes code, int val)
2264
{
2265
	printf("%s 0%o\n", lookup_opcode_name(code), val);
2266
}
2267
2268
static void
2269
dump_cfg_fmtint(ServerOpCodes code, int val)
2270
{
2271
	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2272
}
2273
2274
static void
2275
dump_cfg_string(ServerOpCodes code, const char *val)
2276
{
2277
	printf("%s %s\n", lookup_opcode_name(code),
2278
	    val == NULL ? "none" : val);
2279
}
2280
2281
static void
2282
dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2283
{
2284
	u_int i;
2285
2286
	for (i = 0; i < count; i++)
2287
		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2288
}
2289
2290
static void
2291
dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2292
{
2293
	u_int i;
2294
2295
	if (count <= 0 && code != sAuthenticationMethods)
2296
		return;
2297
	printf("%s", lookup_opcode_name(code));
2298
	for (i = 0; i < count; i++)
2299
		printf(" %s",  vals[i]);
2300
	if (code == sAuthenticationMethods && count == 0)
2301
		printf(" any");
2302
	printf("\n");
2303
}
2304
2305
static char *
2306
format_listen_addrs(struct listenaddr *la)
2307
{
2308
	int r;
2309
	struct addrinfo *ai;
2310
	char addr[NI_MAXHOST], port[NI_MAXSERV];
2311
	char *laddr1 = xstrdup(""), *laddr2 = NULL;
2312
2313
	/*
2314
	 * ListenAddress must be after Port.  add_one_listen_addr pushes
2315
	 * addresses onto a stack, so to maintain ordering we need to
2316
	 * print these in reverse order.
2317
	 */
2318
	for (ai = la->addrs; ai; ai = ai->ai_next) {
2319
		if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2320
		    sizeof(addr), port, sizeof(port),
2321
		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2322
			error("getnameinfo: %.100s", ssh_gai_strerror(r));
2323
			continue;
2324
		}
2325
		laddr2 = laddr1;
2326
		if (ai->ai_family == AF_INET6) {
2327
			xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2328
			    addr, port,
2329
			    la->rdomain == NULL ? "" : " rdomain ",
2330
			    la->rdomain == NULL ? "" : la->rdomain,
2331
			    laddr2);
2332
		} else {
2333
			xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2334
			    addr, port,
2335
			    la->rdomain == NULL ? "" : " rdomain ",
2336
			    la->rdomain == NULL ? "" : la->rdomain,
2337
			    laddr2);
2338
		}
2339
		free(laddr2);
2340
	}
2341
	return laddr1;
2342
}
2343
2344
void
2345
dump_config(ServerOptions *o)
2346
{
2347
	char *s;
2348
	u_int i;
2349
2350
	/* these are usually at the top of the config */
2351
	for (i = 0; i < o->num_ports; i++)
2352
		printf("port %d\n", o->ports[i]);
2353
	dump_cfg_fmtint(sAddressFamily, o->address_family);
2354
2355
	for (i = 0; i < o->num_listen_addrs; i++) {
2356
		s = format_listen_addrs(&o->listen_addrs[i]);
2357
		printf("%s", s);
2358
		free(s);
2359
	}
2360
2361
	/* integer arguments */
2362
	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
2363
	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
2364
	dump_cfg_int(sMaxAuthTries, o->max_authtries);
2365
	dump_cfg_int(sMaxSessions, o->max_sessions);
2366
	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
2367
	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
2368
	dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
2369
2370
	/* formatted integer arguments */
2371
	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
2372
	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
2373
	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
2374
	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
2375
	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
2376
	    o->hostbased_uses_name_from_packet_only);
2377
	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
2378
#ifdef KRB5
2379
	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
2380
	dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
2381
	dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
2382
	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2383
#endif
2384
#ifdef GSSAPI
2385
	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
2386
	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
2387
#endif
2388
	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2389
	dump_cfg_fmtint(sKbdInteractiveAuthentication,
2390
	    o->kbd_interactive_authentication);
2391
	dump_cfg_fmtint(sChallengeResponseAuthentication,
2392
	    o->challenge_response_authentication);
2393
	dump_cfg_fmtint(sPrintMotd, o->print_motd);
2394
	dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
2395
	dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
2396
	dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2397
	dump_cfg_fmtint(sPermitTTY, o->permit_tty);
2398
	dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
2399
	dump_cfg_fmtint(sStrictModes, o->strict_modes);
2400
	dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
2401
	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
2402
	dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
2403
	dump_cfg_fmtint(sCompression, o->compression);
2404
	dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
2405
	dump_cfg_fmtint(sUseDNS, o->use_dns);
2406
	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2407
	dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
2408
	dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
2409
	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2410
	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2411
	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2412
	dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
2413
2414
	/* string arguments */
2415
	dump_cfg_string(sPidFile, o->pid_file);
2416
	dump_cfg_string(sXAuthLocation, o->xauth_location);
2417
	dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT);
2418
	dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC);
2419
	dump_cfg_string(sBanner, o->banner);
2420
	dump_cfg_string(sForceCommand, o->adm_forced_command);
2421
	dump_cfg_string(sChrootDirectory, o->chroot_directory);
2422
	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
2423
	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
2424
	dump_cfg_string(sAuthorizedPrincipalsFile,
2425
	    o->authorized_principals_file);
2426
	dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
2427
	    ? "none" : o->version_addendum);
2428
	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
2429
	dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
2430
	dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
2431
	dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
2432
	dump_cfg_string(sHostKeyAgent, o->host_key_agent);
2433
	dump_cfg_string(sKexAlgorithms,
2434
	    o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
2435
	dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ?
2436
	    o->hostbased_key_types : KEX_DEFAULT_PK_ALG);
2437
	dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ?
2438
	    o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2439
	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
2440
	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2441
	dump_cfg_string(sRDomain, o->routing_domain);
2442
2443
	/* string arguments requiring a lookup */
2444
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2445
	dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
2446
2447
	/* string array arguments */
2448
	dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
2449
	    o->authorized_keys_files);
2450
	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
2451
	     o->host_key_files);
2452
	dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
2453
	     o->host_cert_files);
2454
	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
2455
	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
2456
	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
2457
	dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
2458
	dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
2459
	dump_cfg_strarray_oneline(sAuthenticationMethods,
2460
	    o->num_auth_methods, o->auth_methods);
2461
2462
	/* other arguments */
2463
	for (i = 0; i < o->num_subsystems; i++)
2464
		printf("subsystem %s %s\n", o->subsystem_name[i],
2465
		    o->subsystem_args[i]);
2466
2467
	printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
2468
	    o->max_startups_rate, o->max_startups);
2469
2470
	s = NULL;
2471
	for (i = 0; tunmode_desc[i].val != -1; i++) {
2472
		if (tunmode_desc[i].val == o->permit_tun) {
2473
			s = tunmode_desc[i].text;
2474
			break;
2475
		}
2476
	}
2477
	dump_cfg_string(sPermitTunnel, s);
2478
2479
	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2480
	printf("%s\n", iptos2str(o->ip_qos_bulk));
2481
2482
	printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
2483
	    o->rekey_interval);
2484
2485
	printf("permitopen");
2486
	if (o->num_permitted_opens == 0)
2487
		printf(" any");
2488
	else {
2489
		for (i = 0; i < o->num_permitted_opens; i++)
2490
			printf(" %s", o->permitted_opens[i]);
2491
	}
2492
	printf("\n");
2493
}