• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* $OpenBSD: servconf.c,v 1.222 2011/06/22 21:57:01 djm Exp $ */
2 /*
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  *
6  * As far as I am concerned, the code I have written for this software
7  * can be used freely for any purpose.  Any derived versions of this
8  * software must be clearly marked as such, and if the derived work is
9  * incompatible with the protocol description in the RFC file, it must be
10  * called by a name other than "ssh" or "Secure Shell".
11  */
12 
13 #include "includes.h"
14 
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 
18 #include <netinet/in.h>
19 #include <netinet/in_systm.h>
20 #include <netinet/ip.h>
21 
22 #include <netdb.h>
23 #include <pwd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <stdarg.h>
30 #include <errno.h>
31 
32 #include "openbsd-compat/sys-queue.h"
33 #include "xmalloc.h"
34 #include "ssh.h"
35 #include "log.h"
36 #include "buffer.h"
37 #include "servconf.h"
38 #include "compat.h"
39 #include "pathnames.h"
40 #include "misc.h"
41 #include "cipher.h"
42 #include "key.h"
43 #include "kex.h"
44 #include "mac.h"
45 #include "match.h"
46 #include "channels.h"
47 #include "groupaccess.h"
48 
49 #ifdef ANDROID
50 #include <cutils/properties.h>
51 #endif
52 
53 static void add_listen_addr(ServerOptions *, char *, int);
54 static void add_one_listen_addr(ServerOptions *, char *, int);
55 
56 /* Use of privilege separation or not */
57 extern int use_privsep;
58 extern Buffer cfg;
59 
60 /* Initializes the server options to their default values. */
61 
62 void
initialize_server_options(ServerOptions * options)63 initialize_server_options(ServerOptions *options)
64 {
65 	memset(options, 0, sizeof(*options));
66 
67 	/* Portable-specific options */
68 	options->use_pam = -1;
69 
70 	/* Standard Options */
71 	options->num_ports = 0;
72 	options->ports_from_cmdline = 0;
73 	options->listen_addrs = NULL;
74 	options->address_family = -1;
75 	options->num_host_key_files = 0;
76 	options->num_host_cert_files = 0;
77 	options->pid_file = NULL;
78 	options->server_key_bits = -1;
79 	options->login_grace_time = -1;
80 	options->key_regeneration_time = -1;
81 	options->permit_root_login = PERMIT_NOT_SET;
82 	options->ignore_rhosts = -1;
83 	options->ignore_user_known_hosts = -1;
84 	options->print_motd = -1;
85 	options->print_lastlog = -1;
86 	options->x11_forwarding = -1;
87 	options->x11_display_offset = -1;
88 	options->x11_use_localhost = -1;
89 	options->xauth_location = NULL;
90 	options->strict_modes = -1;
91 	options->tcp_keep_alive = -1;
92 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
93 	options->log_level = SYSLOG_LEVEL_NOT_SET;
94 	options->rhosts_rsa_authentication = -1;
95 	options->hostbased_authentication = -1;
96 	options->hostbased_uses_name_from_packet_only = -1;
97 	options->rsa_authentication = -1;
98 	options->pubkey_authentication = -1;
99 	options->kerberos_authentication = -1;
100 	options->kerberos_or_local_passwd = -1;
101 	options->kerberos_ticket_cleanup = -1;
102 	options->kerberos_get_afs_token = -1;
103 	options->gss_authentication=-1;
104 	options->gss_cleanup_creds = -1;
105 	options->password_authentication = -1;
106 	options->kbd_interactive_authentication = -1;
107 	options->challenge_response_authentication = -1;
108 	options->permit_empty_passwd = -1;
109 	options->permit_user_env = -1;
110 	options->use_login = -1;
111 	options->compression = -1;
112 	options->allow_tcp_forwarding = -1;
113 	options->allow_agent_forwarding = -1;
114 	options->num_allow_users = 0;
115 	options->num_deny_users = 0;
116 	options->num_allow_groups = 0;
117 	options->num_deny_groups = 0;
118 	options->ciphers = NULL;
119 	options->macs = NULL;
120 	options->kex_algorithms = NULL;
121 	options->protocol = SSH_PROTO_UNKNOWN;
122 	options->gateway_ports = -1;
123 	options->num_subsystems = 0;
124 	options->max_startups_begin = -1;
125 	options->max_startups_rate = -1;
126 	options->max_startups = -1;
127 	options->max_authtries = -1;
128 	options->max_sessions = -1;
129 	options->banner = NULL;
130 	options->use_dns = -1;
131 	options->client_alive_interval = -1;
132 	options->client_alive_count_max = -1;
133 	options->num_authkeys_files = 0;
134 	options->num_accept_env = 0;
135 	options->permit_tun = -1;
136 	options->num_permitted_opens = -1;
137 	options->adm_forced_command = NULL;
138 	options->chroot_directory = NULL;
139 	options->zero_knowledge_password_authentication = -1;
140 	options->revoked_keys_file = NULL;
141 	options->trusted_user_ca_keys = NULL;
142 	options->authorized_principals_file = NULL;
143 	options->ip_qos_interactive = -1;
144 	options->ip_qos_bulk = -1;
145 }
146 
147 void
fill_default_server_options(ServerOptions * options)148 fill_default_server_options(ServerOptions *options)
149 {
150 	/* Portable-specific options */
151 	if (options->use_pam == -1)
152 		options->use_pam = 0;
153 
154 	/* Standard Options */
155 	if (options->protocol == SSH_PROTO_UNKNOWN)
156 		options->protocol = SSH_PROTO_2;
157 	if (options->num_host_key_files == 0) {
158 		/* fill default hostkeys for protocols */
159 		if (options->protocol & SSH_PROTO_1)
160 			options->host_key_files[options->num_host_key_files++] =
161 			    _PATH_HOST_KEY_FILE;
162 		if (options->protocol & SSH_PROTO_2) {
163 			options->host_key_files[options->num_host_key_files++] =
164 			    _PATH_HOST_RSA_KEY_FILE;
165 			options->host_key_files[options->num_host_key_files++] =
166 			    _PATH_HOST_DSA_KEY_FILE;
167 #ifdef OPENSSL_HAS_ECC
168 			options->host_key_files[options->num_host_key_files++] =
169 			    _PATH_HOST_ECDSA_KEY_FILE;
170 #endif
171 		}
172 	}
173 	/* No certificates by default */
174 	if (options->num_ports == 0)
175 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
176 	if (options->listen_addrs == NULL)
177 		add_listen_addr(options, NULL, 0);
178 	if (options->pid_file == NULL)
179 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
180 	if (options->server_key_bits == -1)
181 		options->server_key_bits = 1024;
182 	if (options->login_grace_time == -1)
183 		options->login_grace_time = 120;
184 	if (options->key_regeneration_time == -1)
185 		options->key_regeneration_time = 3600;
186 	if (options->permit_root_login == PERMIT_NOT_SET)
187 		options->permit_root_login = PERMIT_YES;
188 	if (options->ignore_rhosts == -1)
189 		options->ignore_rhosts = 1;
190 	if (options->ignore_user_known_hosts == -1)
191 		options->ignore_user_known_hosts = 0;
192 	if (options->print_motd == -1)
193 		options->print_motd = 1;
194 	if (options->print_lastlog == -1)
195 		options->print_lastlog = 1;
196 	if (options->x11_forwarding == -1)
197 		options->x11_forwarding = 0;
198 	if (options->x11_display_offset == -1)
199 		options->x11_display_offset = 10;
200 	if (options->x11_use_localhost == -1)
201 		options->x11_use_localhost = 1;
202 	if (options->xauth_location == NULL)
203 		options->xauth_location = _PATH_XAUTH;
204 	if (options->strict_modes == -1)
205 		options->strict_modes = 1;
206 	if (options->tcp_keep_alive == -1)
207 		options->tcp_keep_alive = 1;
208 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
209 		options->log_facility = SYSLOG_FACILITY_AUTH;
210 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
211 		options->log_level = SYSLOG_LEVEL_INFO;
212 	if (options->rhosts_rsa_authentication == -1)
213 		options->rhosts_rsa_authentication = 0;
214 	if (options->hostbased_authentication == -1)
215 		options->hostbased_authentication = 0;
216 	if (options->hostbased_uses_name_from_packet_only == -1)
217 		options->hostbased_uses_name_from_packet_only = 0;
218 	if (options->rsa_authentication == -1)
219 		options->rsa_authentication = 1;
220 	if (options->pubkey_authentication == -1)
221 		options->pubkey_authentication = 1;
222 	if (options->kerberos_authentication == -1)
223 		options->kerberos_authentication = 0;
224 	if (options->kerberos_or_local_passwd == -1)
225 		options->kerberos_or_local_passwd = 1;
226 	if (options->kerberos_ticket_cleanup == -1)
227 		options->kerberos_ticket_cleanup = 1;
228 	if (options->kerberos_get_afs_token == -1)
229 		options->kerberos_get_afs_token = 0;
230 	if (options->gss_authentication == -1)
231 		options->gss_authentication = 0;
232 	if (options->gss_cleanup_creds == -1)
233 		options->gss_cleanup_creds = 1;
234 	if (options->password_authentication == -1)
235 		options->password_authentication = 1;
236 	if (options->kbd_interactive_authentication == -1)
237 		options->kbd_interactive_authentication = 0;
238 	if (options->challenge_response_authentication == -1)
239 		options->challenge_response_authentication = 1;
240 	if (options->permit_empty_passwd == -1)
241 		options->permit_empty_passwd = 0;
242 	if (options->permit_user_env == -1)
243 		options->permit_user_env = 0;
244 	if (options->use_login == -1)
245 		options->use_login = 0;
246 	if (options->compression == -1)
247 		options->compression = COMP_DELAYED;
248 	if (options->allow_tcp_forwarding == -1)
249 		options->allow_tcp_forwarding = 1;
250 	if (options->allow_agent_forwarding == -1)
251 		options->allow_agent_forwarding = 1;
252 	if (options->gateway_ports == -1)
253 		options->gateway_ports = 0;
254 	if (options->max_startups == -1)
255 		options->max_startups = 10;
256 	if (options->max_startups_rate == -1)
257 		options->max_startups_rate = 100;		/* 100% */
258 	if (options->max_startups_begin == -1)
259 		options->max_startups_begin = options->max_startups;
260 	if (options->max_authtries == -1)
261 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
262 	if (options->max_sessions == -1)
263 		options->max_sessions = DEFAULT_SESSIONS_MAX;
264 	if (options->use_dns == -1)
265 		options->use_dns = 1;
266 	if (options->client_alive_interval == -1)
267 		options->client_alive_interval = 0;
268 	if (options->client_alive_count_max == -1)
269 		options->client_alive_count_max = 3;
270 	if (options->num_authkeys_files == 0) {
271 		options->authorized_keys_files[options->num_authkeys_files++] =
272 		    xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
273 		options->authorized_keys_files[options->num_authkeys_files++] =
274 		    xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2);
275 	}
276 	if (options->permit_tun == -1)
277 		options->permit_tun = SSH_TUNMODE_NO;
278 	if (options->zero_knowledge_password_authentication == -1)
279 		options->zero_knowledge_password_authentication = 0;
280 	if (options->ip_qos_interactive == -1)
281 		options->ip_qos_interactive = IPTOS_LOWDELAY;
282 	if (options->ip_qos_bulk == -1)
283 		options->ip_qos_bulk = IPTOS_THROUGHPUT;
284 
285 	/* Turn privilege separation on by default */
286 	if (use_privsep == -1)
287 		use_privsep = PRIVSEP_ON;
288 
289 #ifndef HAVE_MMAP
290 	if (use_privsep && options->compression == 1) {
291 		error("This platform does not support both privilege "
292 		    "separation and compression");
293 		error("Compression disabled");
294 		options->compression = 0;
295 	}
296 #endif
297 
298 }
299 
300 /* Keyword tokens. */
301 typedef enum {
302 	sBadOption,		/* == unknown option */
303 	/* Portable-specific options */
304 	sUsePAM,
305 	/* Standard Options */
306 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
307 	sPermitRootLogin, sLogFacility, sLogLevel,
308 	sRhostsRSAAuthentication, sRSAAuthentication,
309 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
310 	sKerberosGetAFSToken,
311 	sKerberosTgtPassing, sChallengeResponseAuthentication,
312 	sPasswordAuthentication, sKbdInteractiveAuthentication,
313 	sListenAddress, sAddressFamily,
314 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
315 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
316 	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
317 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
318 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
319 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
320 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
321 	sMaxStartups, sMaxAuthTries, sMaxSessions,
322 	sBanner, sUseDNS, sHostbasedAuthentication,
323 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
324 	sClientAliveCountMax, sAuthorizedKeysFile,
325 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
326 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
327 	sUsePrivilegeSeparation, sAllowAgentForwarding,
328 	sZeroKnowledgePasswordAuthentication, sHostCertificate,
329 	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
330 	sKexAlgorithms, sIPQoS,
331 	sDeprecated, sUnsupported
332 } ServerOpCodes;
333 
334 #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
335 #define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
336 #define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
337 
338 /* Textual representation of the tokens. */
339 static struct {
340 	const char *name;
341 	ServerOpCodes opcode;
342 	u_int flags;
343 } keywords[] = {
344 	/* Portable-specific options */
345 #ifdef USE_PAM
346 	{ "usepam", sUsePAM, SSHCFG_GLOBAL },
347 #else
348 	{ "usepam", sUnsupported, SSHCFG_GLOBAL },
349 #endif
350 	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
351 	/* Standard Options */
352 	{ "port", sPort, SSHCFG_GLOBAL },
353 	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
354 	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
355 	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
356 	{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
357 	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
358 	{ "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
359 	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
360 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
361 	{ "loglevel", sLogLevel, SSHCFG_GLOBAL },
362 	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
363 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
364 	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
365 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
366 	{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
367 	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
368 	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
369 #ifdef KRB5
370 	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
371 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
372 	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
373 #ifdef USE_AFS
374 	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
375 #else
376 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
377 #endif
378 #else
379 	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
380 	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
381 	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
382 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
383 #endif
384 	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
385 	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
386 #ifdef GSSAPI
387 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
388 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
389 #else
390 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
391 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
392 #endif
393 	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
394 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
395 	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
396 	{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
397 #ifdef JPAKE
398 	{ "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
399 #else
400 	{ "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
401 #endif
402 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
403 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
404 	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
405 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
406 	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
407 	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
408 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
409 	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
410 	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
411 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
412 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
413 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
414 	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
415 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
416 	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
417 	{ "compression", sCompression, SSHCFG_GLOBAL },
418 	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
419 	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
420 	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
421 	{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
422 	{ "allowusers", sAllowUsers, SSHCFG_GLOBAL },
423 	{ "denyusers", sDenyUsers, SSHCFG_GLOBAL },
424 	{ "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
425 	{ "denygroups", sDenyGroups, SSHCFG_GLOBAL },
426 	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
427 	{ "macs", sMacs, SSHCFG_GLOBAL },
428 	{ "protocol", sProtocol, SSHCFG_GLOBAL },
429 	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
430 	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
431 	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
432 	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
433 	{ "maxsessions", sMaxSessions, SSHCFG_ALL },
434 	{ "banner", sBanner, SSHCFG_ALL },
435 	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
436 	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
437 	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
438 	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
439 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
440 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
441 	{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
442 	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
443 	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
444 	{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
445 	{ "match", sMatch, SSHCFG_ALL },
446 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
447 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
448 	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
449 	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
450 	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
451 	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
452 	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
453 	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
454 	{ "ipqos", sIPQoS, SSHCFG_ALL },
455 	{ NULL, sBadOption, 0 }
456 };
457 
458 static struct {
459 	int val;
460 	char *text;
461 } tunmode_desc[] = {
462 	{ SSH_TUNMODE_NO, "no" },
463 	{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
464 	{ SSH_TUNMODE_ETHERNET, "ethernet" },
465 	{ SSH_TUNMODE_YES, "yes" },
466 	{ -1, NULL }
467 };
468 
469 /*
470  * Returns the number of the token pointed to by cp or sBadOption.
471  */
472 
473 static ServerOpCodes
parse_token(const char * cp,const char * filename,int linenum,u_int * flags)474 parse_token(const char *cp, const char *filename,
475 	    int linenum, u_int *flags)
476 {
477 	u_int i;
478 
479 	for (i = 0; keywords[i].name; i++)
480 		if (strcasecmp(cp, keywords[i].name) == 0) {
481 			*flags = keywords[i].flags;
482 			return keywords[i].opcode;
483 		}
484 
485 	error("%s: line %d: Bad configuration option: %s",
486 	    filename, linenum, cp);
487 	return sBadOption;
488 }
489 
490 char *
derelativise_path(const char * path)491 derelativise_path(const char *path)
492 {
493 	char *expanded, *ret, cwd[MAXPATHLEN];
494 
495 	expanded = tilde_expand_filename(path, getuid());
496 	if (*expanded == '/')
497 		return expanded;
498 	if (getcwd(cwd, sizeof(cwd)) == NULL)
499 		fatal("%s: getcwd: %s", __func__, strerror(errno));
500 	xasprintf(&ret, "%s/%s", cwd, expanded);
501 	xfree(expanded);
502 	return ret;
503 }
504 
505 static void
add_listen_addr(ServerOptions * options,char * addr,int port)506 add_listen_addr(ServerOptions *options, char *addr, int port)
507 {
508 	u_int i;
509 
510 	if (options->num_ports == 0)
511 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
512 	if (options->address_family == -1)
513 		options->address_family = AF_UNSPEC;
514 	if (port == 0)
515 		for (i = 0; i < options->num_ports; i++)
516 			add_one_listen_addr(options, addr, options->ports[i]);
517 	else
518 		add_one_listen_addr(options, addr, port);
519 }
520 
521 static void
add_one_listen_addr(ServerOptions * options,char * addr,int port)522 add_one_listen_addr(ServerOptions *options, char *addr, int port)
523 {
524 	struct addrinfo hints, *ai, *aitop;
525 	char strport[NI_MAXSERV];
526 	int gaierr;
527 
528 	memset(&hints, 0, sizeof(hints));
529 	hints.ai_family = options->address_family;
530 	hints.ai_socktype = SOCK_STREAM;
531 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
532 	snprintf(strport, sizeof strport, "%d", port);
533 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
534 		fatal("bad addr or host: %s (%s)",
535 		    addr ? addr : "<NULL>",
536 		    ssh_gai_strerror(gaierr));
537 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
538 		;
539 	ai->ai_next = options->listen_addrs;
540 	options->listen_addrs = aitop;
541 }
542 
543 /*
544  * The strategy for the Match blocks is that the config file is parsed twice.
545  *
546  * The first time is at startup.  activep is initialized to 1 and the
547  * directives in the global context are processed and acted on.  Hitting a
548  * Match directive unsets activep and the directives inside the block are
549  * checked for syntax only.
550  *
551  * The second time is after a connection has been established but before
552  * authentication.  activep is initialized to 2 and global config directives
553  * are ignored since they have already been processed.  If the criteria in a
554  * Match block is met, activep is set and the subsequent directives
555  * processed and actioned until EOF or another Match block unsets it.  Any
556  * options set are copied into the main server config.
557  *
558  * Potential additions/improvements:
559  *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
560  *
561  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
562  *	Match Address 192.168.0.*
563  *		Tag trusted
564  *	Match Group wheel
565  *		Tag trusted
566  *	Match Tag trusted
567  *		AllowTcpForwarding yes
568  *		GatewayPorts clientspecified
569  *		[...]
570  *
571  *  - Add a PermittedChannelRequests directive
572  *	Match Group shell
573  *		PermittedChannelRequests session,forwarded-tcpip
574  */
575 
576 static int
match_cfg_line_group(const char * grps,int line,const char * user)577 match_cfg_line_group(const char *grps, int line, const char *user)
578 {
579 	int result = 0;
580 	struct passwd *pw;
581 
582 	if (user == NULL)
583 		goto out;
584 
585 	if ((pw = getpwnam(user)) == NULL) {
586 		debug("Can't match group at line %d because user %.100s does "
587 		    "not exist", line, user);
588 	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
589 		debug("Can't Match group because user %.100s not in any group "
590 		    "at line %d", user, line);
591 	} else if (ga_match_pattern_list(grps) != 1) {
592 		debug("user %.100s does not match group list %.100s at line %d",
593 		    user, grps, line);
594 	} else {
595 		debug("user %.100s matched group list %.100s at line %d", user,
596 		    grps, line);
597 		result = 1;
598 	}
599 out:
600 	ga_free();
601 	return result;
602 }
603 
604 static int
match_cfg_line(char ** condition,int line,const char * user,const char * host,const char * address)605 match_cfg_line(char **condition, int line, const char *user, const char *host,
606     const char *address)
607 {
608 	int result = 1;
609 	char *arg, *attrib, *cp = *condition;
610 	size_t len;
611 
612 	if (user == NULL)
613 		debug3("checking syntax for 'Match %s'", cp);
614 	else
615 		debug3("checking match for '%s' user %s host %s addr %s", cp,
616 		    user ? user : "(null)", host ? host : "(null)",
617 		    address ? address : "(null)");
618 
619 	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
620 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
621 			error("Missing Match criteria for %s", attrib);
622 			return -1;
623 		}
624 		len = strlen(arg);
625 		if (strcasecmp(attrib, "user") == 0) {
626 			if (!user) {
627 				result = 0;
628 				continue;
629 			}
630 			if (match_pattern_list(user, arg, len, 0) != 1)
631 				result = 0;
632 			else
633 				debug("user %.100s matched 'User %.100s' at "
634 				    "line %d", user, arg, line);
635 		} else if (strcasecmp(attrib, "group") == 0) {
636 			switch (match_cfg_line_group(arg, line, user)) {
637 			case -1:
638 				return -1;
639 			case 0:
640 				result = 0;
641 			}
642 		} else if (strcasecmp(attrib, "host") == 0) {
643 			if (!host) {
644 				result = 0;
645 				continue;
646 			}
647 			if (match_hostname(host, arg, len) != 1)
648 				result = 0;
649 			else
650 				debug("connection from %.100s matched 'Host "
651 				    "%.100s' at line %d", host, arg, line);
652 		} else if (strcasecmp(attrib, "address") == 0) {
653 			switch (addr_match_list(address, arg)) {
654 			case 1:
655 				debug("connection from %.100s matched 'Address "
656 				    "%.100s' at line %d", address, arg, line);
657 				break;
658 			case 0:
659 			case -1:
660 				result = 0;
661 				break;
662 			case -2:
663 				return -1;
664 			}
665 		} else {
666 			error("Unsupported Match attribute %s", attrib);
667 			return -1;
668 		}
669 	}
670 	if (user != NULL)
671 		debug3("match %sfound", result ? "" : "not ");
672 	*condition = cp;
673 	return result;
674 }
675 
676 #define WHITESPACE " \t\r\n"
677 
678 /* Multistate option parsing */
679 struct multistate {
680 	char *key;
681 	int value;
682 };
683 static const struct multistate multistate_addressfamily[] = {
684 	{ "inet",			AF_INET },
685 	{ "inet6",			AF_INET6 },
686 	{ "any",			AF_UNSPEC },
687 	{ NULL, -1 }
688 };
689 static const struct multistate multistate_permitrootlogin[] = {
690 	{ "without-password",		PERMIT_NO_PASSWD },
691 	{ "forced-commands-only",	PERMIT_FORCED_ONLY },
692 	{ "yes",			PERMIT_YES },
693 	{ "no",				PERMIT_NO },
694 	{ NULL, -1 }
695 };
696 static const struct multistate multistate_compression[] = {
697 	{ "delayed",			COMP_DELAYED },
698 	{ "yes",			COMP_ZLIB },
699 	{ "no",				COMP_NONE },
700 	{ NULL, -1 }
701 };
702 static const struct multistate multistate_gatewayports[] = {
703 	{ "clientspecified",		2 },
704 	{ "yes",			1 },
705 	{ "no",				0 },
706 	{ NULL, -1 }
707 };
708 static const struct multistate multistate_privsep[] = {
709 	{ "sandbox",			PRIVSEP_SANDBOX },
710 	{ "yes",			PRIVSEP_ON },
711 	{ "no",				PRIVSEP_OFF },
712 	{ NULL, -1 }
713 };
714 
715 int
process_server_config_line(ServerOptions * options,char * line,const char * filename,int linenum,int * activep,const char * user,const char * host,const char * address)716 process_server_config_line(ServerOptions *options, char *line,
717     const char *filename, int linenum, int *activep, const char *user,
718     const char *host, const char *address)
719 {
720 	char *cp, **charptr, *arg, *p;
721 	int cmdline = 0, *intptr, value, value2, n;
722 	SyslogFacility *log_facility_ptr;
723 	LogLevel *log_level_ptr;
724 	ServerOpCodes opcode;
725 	int port;
726 	u_int i, flags = 0;
727 	size_t len;
728 	const struct multistate *multistate_ptr;
729 
730 	cp = line;
731 	if ((arg = strdelim(&cp)) == NULL)
732 		return 0;
733 	/* Ignore leading whitespace */
734 	if (*arg == '\0')
735 		arg = strdelim(&cp);
736 	if (!arg || !*arg || *arg == '#')
737 		return 0;
738 	intptr = NULL;
739 	charptr = NULL;
740 	opcode = parse_token(arg, filename, linenum, &flags);
741 
742 	if (activep == NULL) { /* We are processing a command line directive */
743 		cmdline = 1;
744 		activep = &cmdline;
745 	}
746 	if (*activep && opcode != sMatch)
747 		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
748 	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
749 		if (user == NULL) {
750 			fatal("%s line %d: Directive '%s' is not allowed "
751 			    "within a Match block", filename, linenum, arg);
752 		} else { /* this is a directive we have already processed */
753 			while (arg)
754 				arg = strdelim(&cp);
755 			return 0;
756 		}
757 	}
758 
759 	switch (opcode) {
760 	/* Portable-specific options */
761 	case sUsePAM:
762 		intptr = &options->use_pam;
763 		goto parse_flag;
764 
765 	/* Standard Options */
766 	case sBadOption:
767 		return -1;
768 	case sPort:
769 		/* ignore ports from configfile if cmdline specifies ports */
770 		if (options->ports_from_cmdline)
771 			return 0;
772 		if (options->listen_addrs != NULL)
773 			fatal("%s line %d: ports must be specified before "
774 			    "ListenAddress.", filename, linenum);
775 		if (options->num_ports >= MAX_PORTS)
776 			fatal("%s line %d: too many ports.",
777 			    filename, linenum);
778 		arg = strdelim(&cp);
779 		if (!arg || *arg == '\0')
780 			fatal("%s line %d: missing port number.",
781 			    filename, linenum);
782 		options->ports[options->num_ports++] = a2port(arg);
783 		if (options->ports[options->num_ports-1] <= 0)
784 			fatal("%s line %d: Badly formatted port number.",
785 			    filename, linenum);
786 		break;
787 
788 	case sServerKeyBits:
789 		intptr = &options->server_key_bits;
790  parse_int:
791 		arg = strdelim(&cp);
792 		if (!arg || *arg == '\0')
793 			fatal("%s line %d: missing integer value.",
794 			    filename, linenum);
795 		value = atoi(arg);
796 		if (*activep && *intptr == -1)
797 			*intptr = value;
798 		break;
799 
800 	case sLoginGraceTime:
801 		intptr = &options->login_grace_time;
802  parse_time:
803 		arg = strdelim(&cp);
804 		if (!arg || *arg == '\0')
805 			fatal("%s line %d: missing time value.",
806 			    filename, linenum);
807 		if ((value = convtime(arg)) == -1)
808 			fatal("%s line %d: invalid time value.",
809 			    filename, linenum);
810 		if (*intptr == -1)
811 			*intptr = value;
812 		break;
813 
814 	case sKeyRegenerationTime:
815 		intptr = &options->key_regeneration_time;
816 		goto parse_time;
817 
818 	case sListenAddress:
819 		arg = strdelim(&cp);
820 		if (arg == NULL || *arg == '\0')
821 			fatal("%s line %d: missing address",
822 			    filename, linenum);
823 		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
824 		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
825 		    && strchr(p+1, ':') != NULL) {
826 			add_listen_addr(options, arg, 0);
827 			break;
828 		}
829 		p = hpdelim(&arg);
830 		if (p == NULL)
831 			fatal("%s line %d: bad address:port usage",
832 			    filename, linenum);
833 		p = cleanhostname(p);
834 		if (arg == NULL)
835 			port = 0;
836 		else if ((port = a2port(arg)) <= 0)
837 			fatal("%s line %d: bad port number", filename, linenum);
838 
839 		add_listen_addr(options, p, port);
840 
841 		break;
842 
843 	case sAddressFamily:
844 		intptr = &options->address_family;
845 		multistate_ptr = multistate_addressfamily;
846 		if (options->listen_addrs != NULL)
847 			fatal("%s line %d: address family must be specified "
848 			    "before ListenAddress.", filename, linenum);
849  parse_multistate:
850 		arg = strdelim(&cp);
851 		if (!arg || *arg == '\0')
852 			fatal("%s line %d: missing argument.",
853 			    filename, linenum);
854 		value = -1;
855 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
856 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
857 				value = multistate_ptr[i].value;
858 				break;
859 			}
860 		}
861 		if (value == -1)
862 			fatal("%s line %d: unsupported option \"%s\".",
863 			    filename, linenum, arg);
864 		if (*activep && *intptr == -1)
865 			*intptr = value;
866 		break;
867 
868 	case sHostKeyFile:
869 		intptr = &options->num_host_key_files;
870 		if (*intptr >= MAX_HOSTKEYS)
871 			fatal("%s line %d: too many host keys specified (max %d).",
872 			    filename, linenum, MAX_HOSTKEYS);
873 		charptr = &options->host_key_files[*intptr];
874  parse_filename:
875 		arg = strdelim(&cp);
876 		if (!arg || *arg == '\0')
877 			fatal("%s line %d: missing file name.",
878 			    filename, linenum);
879 		if (*activep && *charptr == NULL) {
880 			*charptr = derelativise_path(arg);
881 			/* increase optional counter */
882 			if (intptr != NULL)
883 				*intptr = *intptr + 1;
884 		}
885 		break;
886 
887 	case sHostCertificate:
888 		intptr = &options->num_host_cert_files;
889 		if (*intptr >= MAX_HOSTKEYS)
890 			fatal("%s line %d: too many host certificates "
891 			    "specified (max %d).", filename, linenum,
892 			    MAX_HOSTCERTS);
893 		charptr = &options->host_cert_files[*intptr];
894 		goto parse_filename;
895 		break;
896 
897 	case sPidFile:
898 		charptr = &options->pid_file;
899 		goto parse_filename;
900 
901 	case sPermitRootLogin:
902 		intptr = &options->permit_root_login;
903 		multistate_ptr = multistate_permitrootlogin;
904 		goto parse_multistate;
905 
906 	case sIgnoreRhosts:
907 		intptr = &options->ignore_rhosts;
908  parse_flag:
909 		arg = strdelim(&cp);
910 		if (!arg || *arg == '\0')
911 			fatal("%s line %d: missing yes/no argument.",
912 			    filename, linenum);
913 		value = 0;	/* silence compiler */
914 		if (strcmp(arg, "yes") == 0)
915 			value = 1;
916 		else if (strcmp(arg, "no") == 0)
917 			value = 0;
918 		else
919 			fatal("%s line %d: Bad yes/no argument: %s",
920 				filename, linenum, arg);
921 		if (*activep && *intptr == -1)
922 			*intptr = value;
923 		break;
924 
925 	case sIgnoreUserKnownHosts:
926 		intptr = &options->ignore_user_known_hosts;
927 		goto parse_flag;
928 
929 	case sRhostsRSAAuthentication:
930 		intptr = &options->rhosts_rsa_authentication;
931 		goto parse_flag;
932 
933 	case sHostbasedAuthentication:
934 		intptr = &options->hostbased_authentication;
935 		goto parse_flag;
936 
937 	case sHostbasedUsesNameFromPacketOnly:
938 		intptr = &options->hostbased_uses_name_from_packet_only;
939 		goto parse_flag;
940 
941 	case sRSAAuthentication:
942 		intptr = &options->rsa_authentication;
943 		goto parse_flag;
944 
945 	case sPubkeyAuthentication:
946 		intptr = &options->pubkey_authentication;
947 		goto parse_flag;
948 
949 	case sKerberosAuthentication:
950 		intptr = &options->kerberos_authentication;
951 		goto parse_flag;
952 
953 	case sKerberosOrLocalPasswd:
954 		intptr = &options->kerberos_or_local_passwd;
955 		goto parse_flag;
956 
957 	case sKerberosTicketCleanup:
958 		intptr = &options->kerberos_ticket_cleanup;
959 		goto parse_flag;
960 
961 	case sKerberosGetAFSToken:
962 		intptr = &options->kerberos_get_afs_token;
963 		goto parse_flag;
964 
965 	case sGssAuthentication:
966 		intptr = &options->gss_authentication;
967 		goto parse_flag;
968 
969 	case sGssCleanupCreds:
970 		intptr = &options->gss_cleanup_creds;
971 		goto parse_flag;
972 
973 	case sPasswordAuthentication:
974 		intptr = &options->password_authentication;
975 		goto parse_flag;
976 
977 	case sZeroKnowledgePasswordAuthentication:
978 		intptr = &options->zero_knowledge_password_authentication;
979 		goto parse_flag;
980 
981 	case sKbdInteractiveAuthentication:
982 		intptr = &options->kbd_interactive_authentication;
983 		goto parse_flag;
984 
985 	case sChallengeResponseAuthentication:
986 		intptr = &options->challenge_response_authentication;
987 		goto parse_flag;
988 
989 	case sPrintMotd:
990 		intptr = &options->print_motd;
991 		goto parse_flag;
992 
993 	case sPrintLastLog:
994 		intptr = &options->print_lastlog;
995 		goto parse_flag;
996 
997 	case sX11Forwarding:
998 		intptr = &options->x11_forwarding;
999 		goto parse_flag;
1000 
1001 	case sX11DisplayOffset:
1002 		intptr = &options->x11_display_offset;
1003 		goto parse_int;
1004 
1005 	case sX11UseLocalhost:
1006 		intptr = &options->x11_use_localhost;
1007 		goto parse_flag;
1008 
1009 	case sXAuthLocation:
1010 		charptr = &options->xauth_location;
1011 		goto parse_filename;
1012 
1013 	case sStrictModes:
1014 		intptr = &options->strict_modes;
1015 		goto parse_flag;
1016 
1017 	case sTCPKeepAlive:
1018 		intptr = &options->tcp_keep_alive;
1019 		goto parse_flag;
1020 
1021 	case sEmptyPasswd:
1022 		intptr = &options->permit_empty_passwd;
1023 		goto parse_flag;
1024 
1025 	case sPermitUserEnvironment:
1026 		intptr = &options->permit_user_env;
1027 		goto parse_flag;
1028 
1029 	case sUseLogin:
1030 		intptr = &options->use_login;
1031 		goto parse_flag;
1032 
1033 	case sCompression:
1034 		intptr = &options->compression;
1035 		multistate_ptr = multistate_compression;
1036 		goto parse_multistate;
1037 
1038 	case sGatewayPorts:
1039 		intptr = &options->gateway_ports;
1040 		multistate_ptr = multistate_gatewayports;
1041 		goto parse_multistate;
1042 
1043 	case sUseDNS:
1044 		intptr = &options->use_dns;
1045 		goto parse_flag;
1046 
1047 	case sLogFacility:
1048 		log_facility_ptr = &options->log_facility;
1049 		arg = strdelim(&cp);
1050 		value = log_facility_number(arg);
1051 		if (value == SYSLOG_FACILITY_NOT_SET)
1052 			fatal("%.200s line %d: unsupported log facility '%s'",
1053 			    filename, linenum, arg ? arg : "<NONE>");
1054 		if (*log_facility_ptr == -1)
1055 			*log_facility_ptr = (SyslogFacility) value;
1056 		break;
1057 
1058 	case sLogLevel:
1059 		log_level_ptr = &options->log_level;
1060 		arg = strdelim(&cp);
1061 		value = log_level_number(arg);
1062 		if (value == SYSLOG_LEVEL_NOT_SET)
1063 			fatal("%.200s line %d: unsupported log level '%s'",
1064 			    filename, linenum, arg ? arg : "<NONE>");
1065 		if (*log_level_ptr == -1)
1066 			*log_level_ptr = (LogLevel) value;
1067 		break;
1068 
1069 	case sAllowTcpForwarding:
1070 		intptr = &options->allow_tcp_forwarding;
1071 		goto parse_flag;
1072 
1073 	case sAllowAgentForwarding:
1074 		intptr = &options->allow_agent_forwarding;
1075 		goto parse_flag;
1076 
1077 	case sUsePrivilegeSeparation:
1078 		intptr = &use_privsep;
1079 		multistate_ptr = multistate_privsep;
1080 		goto parse_multistate;
1081 
1082 	case sAllowUsers:
1083 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1084 			if (options->num_allow_users >= MAX_ALLOW_USERS)
1085 				fatal("%s line %d: too many allow users.",
1086 				    filename, linenum);
1087 			options->allow_users[options->num_allow_users++] =
1088 			    xstrdup(arg);
1089 		}
1090 		break;
1091 
1092 	case sDenyUsers:
1093 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1094 			if (options->num_deny_users >= MAX_DENY_USERS)
1095 				fatal("%s line %d: too many deny users.",
1096 				    filename, linenum);
1097 			options->deny_users[options->num_deny_users++] =
1098 			    xstrdup(arg);
1099 		}
1100 		break;
1101 
1102 	case sAllowGroups:
1103 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1104 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1105 				fatal("%s line %d: too many allow groups.",
1106 				    filename, linenum);
1107 			options->allow_groups[options->num_allow_groups++] =
1108 			    xstrdup(arg);
1109 		}
1110 		break;
1111 
1112 	case sDenyGroups:
1113 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1114 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
1115 				fatal("%s line %d: too many deny groups.",
1116 				    filename, linenum);
1117 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1118 		}
1119 		break;
1120 
1121 	case sCiphers:
1122 		arg = strdelim(&cp);
1123 		if (!arg || *arg == '\0')
1124 			fatal("%s line %d: Missing argument.", filename, linenum);
1125 		if (!ciphers_valid(arg))
1126 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1127 			    filename, linenum, arg ? arg : "<NONE>");
1128 		if (options->ciphers == NULL)
1129 			options->ciphers = xstrdup(arg);
1130 		break;
1131 
1132 	case sMacs:
1133 		arg = strdelim(&cp);
1134 		if (!arg || *arg == '\0')
1135 			fatal("%s line %d: Missing argument.", filename, linenum);
1136 		if (!mac_valid(arg))
1137 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1138 			    filename, linenum, arg ? arg : "<NONE>");
1139 		if (options->macs == NULL)
1140 			options->macs = xstrdup(arg);
1141 		break;
1142 
1143 	case sKexAlgorithms:
1144 		arg = strdelim(&cp);
1145 		if (!arg || *arg == '\0')
1146 			fatal("%s line %d: Missing argument.",
1147 			    filename, linenum);
1148 		if (!kex_names_valid(arg))
1149 			fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1150 			    filename, linenum, arg ? arg : "<NONE>");
1151 		if (options->kex_algorithms == NULL)
1152 			options->kex_algorithms = xstrdup(arg);
1153 		break;
1154 
1155 	case sProtocol:
1156 		intptr = &options->protocol;
1157 		arg = strdelim(&cp);
1158 		if (!arg || *arg == '\0')
1159 			fatal("%s line %d: Missing argument.", filename, linenum);
1160 		value = proto_spec(arg);
1161 		if (value == SSH_PROTO_UNKNOWN)
1162 			fatal("%s line %d: Bad protocol spec '%s'.",
1163 			    filename, linenum, arg ? arg : "<NONE>");
1164 		if (*intptr == SSH_PROTO_UNKNOWN)
1165 			*intptr = value;
1166 		break;
1167 
1168 	case sSubsystem:
1169 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1170 			fatal("%s line %d: too many subsystems defined.",
1171 			    filename, linenum);
1172 		}
1173 		arg = strdelim(&cp);
1174 		if (!arg || *arg == '\0')
1175 			fatal("%s line %d: Missing subsystem name.",
1176 			    filename, linenum);
1177 		if (!*activep) {
1178 			arg = strdelim(&cp);
1179 			break;
1180 		}
1181 		for (i = 0; i < options->num_subsystems; i++)
1182 			if (strcmp(arg, options->subsystem_name[i]) == 0)
1183 				fatal("%s line %d: Subsystem '%s' already defined.",
1184 				    filename, linenum, arg);
1185 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1186 		arg = strdelim(&cp);
1187 		if (!arg || *arg == '\0')
1188 			fatal("%s line %d: Missing subsystem command.",
1189 			    filename, linenum);
1190 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1191 
1192 		/* Collect arguments (separate to executable) */
1193 		p = xstrdup(arg);
1194 		len = strlen(p) + 1;
1195 		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1196 			len += 1 + strlen(arg);
1197 			p = xrealloc(p, 1, len);
1198 			strlcat(p, " ", len);
1199 			strlcat(p, arg, len);
1200 		}
1201 		options->subsystem_args[options->num_subsystems] = p;
1202 		options->num_subsystems++;
1203 		break;
1204 
1205 	case sMaxStartups:
1206 		arg = strdelim(&cp);
1207 		if (!arg || *arg == '\0')
1208 			fatal("%s line %d: Missing MaxStartups spec.",
1209 			    filename, linenum);
1210 		if ((n = sscanf(arg, "%d:%d:%d",
1211 		    &options->max_startups_begin,
1212 		    &options->max_startups_rate,
1213 		    &options->max_startups)) == 3) {
1214 			if (options->max_startups_begin >
1215 			    options->max_startups ||
1216 			    options->max_startups_rate > 100 ||
1217 			    options->max_startups_rate < 1)
1218 				fatal("%s line %d: Illegal MaxStartups spec.",
1219 				    filename, linenum);
1220 		} else if (n != 1)
1221 			fatal("%s line %d: Illegal MaxStartups spec.",
1222 			    filename, linenum);
1223 		else
1224 			options->max_startups = options->max_startups_begin;
1225 		break;
1226 
1227 	case sMaxAuthTries:
1228 		intptr = &options->max_authtries;
1229 		goto parse_int;
1230 
1231 	case sMaxSessions:
1232 		intptr = &options->max_sessions;
1233 		goto parse_int;
1234 
1235 	case sBanner:
1236 		charptr = &options->banner;
1237 		goto parse_filename;
1238 
1239 	/*
1240 	 * These options can contain %X options expanded at
1241 	 * connect time, so that you can specify paths like:
1242 	 *
1243 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1244 	 */
1245 	case sAuthorizedKeysFile:
1246 		if (*activep && options->num_authkeys_files == 0) {
1247 			while ((arg = strdelim(&cp)) && *arg != '\0') {
1248 				if (options->num_authkeys_files >=
1249 				    MAX_AUTHKEYS_FILES)
1250 					fatal("%s line %d: "
1251 					    "too many authorized keys files.",
1252 					    filename, linenum);
1253 				options->authorized_keys_files[
1254 				    options->num_authkeys_files++] =
1255 				    tilde_expand_filename(arg, getuid());
1256 			}
1257 		}
1258 		return 0;
1259 
1260 	case sAuthorizedPrincipalsFile:
1261 		charptr = &options->authorized_principals_file;
1262 		arg = strdelim(&cp);
1263 		if (!arg || *arg == '\0')
1264 			fatal("%s line %d: missing file name.",
1265 			    filename, linenum);
1266 		if (*activep && *charptr == NULL) {
1267 			*charptr = tilde_expand_filename(arg, getuid());
1268 			/* increase optional counter */
1269 			if (intptr != NULL)
1270 				*intptr = *intptr + 1;
1271 		}
1272 		break;
1273 
1274 	case sClientAliveInterval:
1275 		intptr = &options->client_alive_interval;
1276 		goto parse_time;
1277 
1278 	case sClientAliveCountMax:
1279 		intptr = &options->client_alive_count_max;
1280 		goto parse_int;
1281 
1282 	case sAcceptEnv:
1283 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1284 			if (strchr(arg, '=') != NULL)
1285 				fatal("%s line %d: Invalid environment name.",
1286 				    filename, linenum);
1287 			if (options->num_accept_env >= MAX_ACCEPT_ENV)
1288 				fatal("%s line %d: too many allow env.",
1289 				    filename, linenum);
1290 			if (!*activep)
1291 				break;
1292 			options->accept_env[options->num_accept_env++] =
1293 			    xstrdup(arg);
1294 		}
1295 		break;
1296 
1297 	case sPermitTunnel:
1298 		intptr = &options->permit_tun;
1299 		arg = strdelim(&cp);
1300 		if (!arg || *arg == '\0')
1301 			fatal("%s line %d: Missing yes/point-to-point/"
1302 			    "ethernet/no argument.", filename, linenum);
1303 		value = -1;
1304 		for (i = 0; tunmode_desc[i].val != -1; i++)
1305 			if (strcmp(tunmode_desc[i].text, arg) == 0) {
1306 				value = tunmode_desc[i].val;
1307 				break;
1308 			}
1309 		if (value == -1)
1310 			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1311 			    "no argument: %s", filename, linenum, arg);
1312 		if (*intptr == -1)
1313 			*intptr = value;
1314 		break;
1315 
1316 	case sMatch:
1317 		if (cmdline)
1318 			fatal("Match directive not supported as a command-line "
1319 			   "option");
1320 		value = match_cfg_line(&cp, linenum, user, host, address);
1321 		if (value < 0)
1322 			fatal("%s line %d: Bad Match condition", filename,
1323 			    linenum);
1324 		*activep = value;
1325 		break;
1326 
1327 	case sPermitOpen:
1328 		arg = strdelim(&cp);
1329 		if (!arg || *arg == '\0')
1330 			fatal("%s line %d: missing PermitOpen specification",
1331 			    filename, linenum);
1332 		n = options->num_permitted_opens;	/* modified later */
1333 		if (strcmp(arg, "any") == 0) {
1334 			if (*activep && n == -1) {
1335 				channel_clear_adm_permitted_opens();
1336 				options->num_permitted_opens = 0;
1337 			}
1338 			break;
1339 		}
1340 		if (*activep && n == -1)
1341 			channel_clear_adm_permitted_opens();
1342 		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1343 			p = hpdelim(&arg);
1344 			if (p == NULL)
1345 				fatal("%s line %d: missing host in PermitOpen",
1346 				    filename, linenum);
1347 			p = cleanhostname(p);
1348 			if (arg == NULL || (port = a2port(arg)) <= 0)
1349 				fatal("%s line %d: bad port number in "
1350 				    "PermitOpen", filename, linenum);
1351 			if (*activep && n == -1)
1352 				options->num_permitted_opens =
1353 				    channel_add_adm_permitted_opens(p, port);
1354 		}
1355 		break;
1356 
1357 	case sForceCommand:
1358 		if (cp == NULL)
1359 			fatal("%.200s line %d: Missing argument.", filename,
1360 			    linenum);
1361 		len = strspn(cp, WHITESPACE);
1362 		if (*activep && options->adm_forced_command == NULL)
1363 			options->adm_forced_command = xstrdup(cp + len);
1364 		return 0;
1365 
1366 	case sChrootDirectory:
1367 		charptr = &options->chroot_directory;
1368 
1369 		arg = strdelim(&cp);
1370 		if (!arg || *arg == '\0')
1371 			fatal("%s line %d: missing file name.",
1372 			    filename, linenum);
1373 		if (*activep && *charptr == NULL)
1374 			*charptr = xstrdup(arg);
1375 		break;
1376 
1377 	case sTrustedUserCAKeys:
1378 		charptr = &options->trusted_user_ca_keys;
1379 		goto parse_filename;
1380 
1381 	case sRevokedKeys:
1382 		charptr = &options->revoked_keys_file;
1383 		goto parse_filename;
1384 
1385 	case sIPQoS:
1386 		arg = strdelim(&cp);
1387 		if ((value = parse_ipqos(arg)) == -1)
1388 			fatal("%s line %d: Bad IPQoS value: %s",
1389 			    filename, linenum, arg);
1390 		arg = strdelim(&cp);
1391 		if (arg == NULL)
1392 			value2 = value;
1393 		else if ((value2 = parse_ipqos(arg)) == -1)
1394 			fatal("%s line %d: Bad IPQoS value: %s",
1395 			    filename, linenum, arg);
1396 		if (*activep) {
1397 			options->ip_qos_interactive = value;
1398 			options->ip_qos_bulk = value2;
1399 		}
1400 		break;
1401 
1402 	case sDeprecated:
1403 		logit("%s line %d: Deprecated option %s",
1404 		    filename, linenum, arg);
1405 		while (arg)
1406 		    arg = strdelim(&cp);
1407 		break;
1408 
1409 	case sUnsupported:
1410 		logit("%s line %d: Unsupported option %s",
1411 		    filename, linenum, arg);
1412 		while (arg)
1413 		    arg = strdelim(&cp);
1414 		break;
1415 
1416 	default:
1417 		fatal("%s line %d: Missing handler for opcode %s (%d)",
1418 		    filename, linenum, arg, opcode);
1419 	}
1420 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1421 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
1422 		    filename, linenum, arg);
1423 	return 0;
1424 }
1425 
1426 /* Reads the server configuration file. */
1427 
1428 void
load_server_config(const char * filename,Buffer * conf)1429 load_server_config(const char *filename, Buffer *conf)
1430 {
1431 	char line[1024], *cp;
1432 	FILE *f;
1433 
1434 	debug2("%s: filename %s", __func__, filename);
1435 	if ((f = fopen(filename, "r")) == NULL) {
1436 		perror(filename);
1437 		exit(1);
1438 	}
1439 	buffer_clear(conf);
1440 	while (fgets(line, sizeof(line), f)) {
1441 		/*
1442 		 * Trim out comments and strip whitespace
1443 		 * NB - preserve newlines, they are needed to reproduce
1444 		 * line numbers later for error messages
1445 		 */
1446 		if ((cp = strchr(line, '#')) != NULL)
1447 			memcpy(cp, "\n", 2);
1448 		cp = line + strspn(line, " \t\r");
1449 
1450 		buffer_append(conf, cp, strlen(cp));
1451 	}
1452 	buffer_append(conf, "\0", 1);
1453 	fclose(f);
1454 	debug2("%s: done config len = %d", __func__, buffer_len(conf));
1455 }
1456 
1457 void
parse_server_match_config(ServerOptions * options,const char * user,const char * host,const char * address)1458 parse_server_match_config(ServerOptions *options, const char *user,
1459     const char *host, const char *address)
1460 {
1461 	ServerOptions mo;
1462 #ifdef ANDROID
1463 	char value[PROPERTY_VALUE_MAX];
1464 #endif
1465 
1466 	initialize_server_options(&mo);
1467 	parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1468 #ifdef ANDROID
1469 	/* Allow root login if ro.debuggable is set */
1470 	property_get("ro.debuggable", value, "");
1471 	if (strcmp(value, "1") == 0)
1472 		mo.permit_root_login = PERMIT_YES;
1473 #endif
1474 	copy_set_server_options(options, &mo, 0);
1475 }
1476 
1477 /* Helper macros */
1478 #define M_CP_INTOPT(n) do {\
1479 	if (src->n != -1) \
1480 		dst->n = src->n; \
1481 } while (0)
1482 #define M_CP_STROPT(n) do {\
1483 	if (src->n != NULL) { \
1484 		if (dst->n != NULL) \
1485 			xfree(dst->n); \
1486 		dst->n = src->n; \
1487 	} \
1488 } while(0)
1489 #define M_CP_STRARRAYOPT(n, num_n) do {\
1490 	if (src->num_n != 0) { \
1491 		for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \
1492 			dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \
1493 	} \
1494 } while(0)
1495 
1496 /*
1497  * Copy any supported values that are set.
1498  *
1499  * If the preauth flag is set, we do not bother copying the string or
1500  * array values that are not used pre-authentication, because any that we
1501  * do use must be explictly sent in mm_getpwnamallow().
1502  */
1503 void
copy_set_server_options(ServerOptions * dst,ServerOptions * src,int preauth)1504 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1505 {
1506 	M_CP_INTOPT(password_authentication);
1507 	M_CP_INTOPT(gss_authentication);
1508 	M_CP_INTOPT(rsa_authentication);
1509 	M_CP_INTOPT(pubkey_authentication);
1510 	M_CP_INTOPT(kerberos_authentication);
1511 	M_CP_INTOPT(hostbased_authentication);
1512 	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1513 	M_CP_INTOPT(kbd_interactive_authentication);
1514 	M_CP_INTOPT(zero_knowledge_password_authentication);
1515 	M_CP_INTOPT(permit_root_login);
1516 	M_CP_INTOPT(permit_empty_passwd);
1517 
1518 	M_CP_INTOPT(allow_tcp_forwarding);
1519 	M_CP_INTOPT(allow_agent_forwarding);
1520 	M_CP_INTOPT(permit_tun);
1521 	M_CP_INTOPT(gateway_ports);
1522 	M_CP_INTOPT(x11_display_offset);
1523 	M_CP_INTOPT(x11_forwarding);
1524 	M_CP_INTOPT(x11_use_localhost);
1525 	M_CP_INTOPT(max_sessions);
1526 	M_CP_INTOPT(max_authtries);
1527 	M_CP_INTOPT(ip_qos_interactive);
1528 	M_CP_INTOPT(ip_qos_bulk);
1529 
1530 	/* See comment in servconf.h */
1531 	COPY_MATCH_STRING_OPTS();
1532 
1533 	/*
1534 	 * The only things that should be below this point are string options
1535 	 * which are only used after authentication.
1536 	 */
1537 	if (preauth)
1538 		return;
1539 
1540 	M_CP_STROPT(adm_forced_command);
1541 	M_CP_STROPT(chroot_directory);
1542 }
1543 
1544 #undef M_CP_INTOPT
1545 #undef M_CP_STROPT
1546 #undef M_CP_STRARRAYOPT
1547 
1548 void
parse_server_config(ServerOptions * options,const char * filename,Buffer * conf,const char * user,const char * host,const char * address)1549 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1550     const char *user, const char *host, const char *address)
1551 {
1552 	int active, linenum, bad_options = 0;
1553 	char *cp, *obuf, *cbuf;
1554 
1555 	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1556 
1557 	obuf = cbuf = xstrdup(buffer_ptr(conf));
1558 	active = user ? 0 : 1;
1559 	linenum = 1;
1560 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
1561 		if (process_server_config_line(options, cp, filename,
1562 		    linenum++, &active, user, host, address) != 0)
1563 			bad_options++;
1564 	}
1565 	xfree(obuf);
1566 	if (bad_options > 0)
1567 		fatal("%s: terminating, %d bad configuration options",
1568 		    filename, bad_options);
1569 }
1570 
1571 static const char *
fmt_multistate_int(int val,const struct multistate * m)1572 fmt_multistate_int(int val, const struct multistate *m)
1573 {
1574 	u_int i;
1575 
1576 	for (i = 0; m[i].key != NULL; i++) {
1577 		if (m[i].value == val)
1578 			return m[i].key;
1579 	}
1580 	return "UNKNOWN";
1581 }
1582 
1583 static const char *
fmt_intarg(ServerOpCodes code,int val)1584 fmt_intarg(ServerOpCodes code, int val)
1585 {
1586 	if (val == -1)
1587 		return "unset";
1588 	switch (code) {
1589 	case sAddressFamily:
1590 		return fmt_multistate_int(val, multistate_addressfamily);
1591 	case sPermitRootLogin:
1592 		return fmt_multistate_int(val, multistate_permitrootlogin);
1593 	case sGatewayPorts:
1594 		return fmt_multistate_int(val, multistate_gatewayports);
1595 	case sCompression:
1596 		return fmt_multistate_int(val, multistate_compression);
1597 	case sUsePrivilegeSeparation:
1598 		return fmt_multistate_int(val, multistate_privsep);
1599 	case sProtocol:
1600 		switch (val) {
1601 		case SSH_PROTO_1:
1602 			return "1";
1603 		case SSH_PROTO_2:
1604 			return "2";
1605 		case (SSH_PROTO_1|SSH_PROTO_2):
1606 			return "2,1";
1607 		default:
1608 			return "UNKNOWN";
1609 		}
1610 	default:
1611 		switch (val) {
1612 		case 0:
1613 			return "no";
1614 		case 1:
1615 			return "yes";
1616 		default:
1617 			return "UNKNOWN";
1618 		}
1619 	}
1620 }
1621 
1622 static const char *
lookup_opcode_name(ServerOpCodes code)1623 lookup_opcode_name(ServerOpCodes code)
1624 {
1625 	u_int i;
1626 
1627 	for (i = 0; keywords[i].name != NULL; i++)
1628 		if (keywords[i].opcode == code)
1629 			return(keywords[i].name);
1630 	return "UNKNOWN";
1631 }
1632 
1633 static void
dump_cfg_int(ServerOpCodes code,int val)1634 dump_cfg_int(ServerOpCodes code, int val)
1635 {
1636 	printf("%s %d\n", lookup_opcode_name(code), val);
1637 }
1638 
1639 static void
dump_cfg_fmtint(ServerOpCodes code,int val)1640 dump_cfg_fmtint(ServerOpCodes code, int val)
1641 {
1642 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1643 }
1644 
1645 static void
dump_cfg_string(ServerOpCodes code,const char * val)1646 dump_cfg_string(ServerOpCodes code, const char *val)
1647 {
1648 	if (val == NULL)
1649 		return;
1650 	printf("%s %s\n", lookup_opcode_name(code), val);
1651 }
1652 
1653 static void
dump_cfg_strarray(ServerOpCodes code,u_int count,char ** vals)1654 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1655 {
1656 	u_int i;
1657 
1658 	for (i = 0; i < count; i++)
1659 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
1660 }
1661 
1662 static void
dump_cfg_strarray_oneline(ServerOpCodes code,u_int count,char ** vals)1663 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
1664 {
1665 	u_int i;
1666 
1667 	printf("%s", lookup_opcode_name(code));
1668 	for (i = 0; i < count; i++)
1669 		printf(" %s",  vals[i]);
1670 	printf("\n");
1671 }
1672 
1673 void
dump_config(ServerOptions * o)1674 dump_config(ServerOptions *o)
1675 {
1676 	u_int i;
1677 	int ret;
1678 	struct addrinfo *ai;
1679 	char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1680 
1681 	/* these are usually at the top of the config */
1682 	for (i = 0; i < o->num_ports; i++)
1683 		printf("port %d\n", o->ports[i]);
1684 	dump_cfg_fmtint(sProtocol, o->protocol);
1685 	dump_cfg_fmtint(sAddressFamily, o->address_family);
1686 
1687 	/* ListenAddress must be after Port */
1688 	for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1689 		if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1690 		    sizeof(addr), port, sizeof(port),
1691 		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1692 			error("getnameinfo failed: %.100s",
1693 			    (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1694 			    strerror(errno));
1695 		} else {
1696 			if (ai->ai_family == AF_INET6)
1697 				printf("listenaddress [%s]:%s\n", addr, port);
1698 			else
1699 				printf("listenaddress %s:%s\n", addr, port);
1700 		}
1701 	}
1702 
1703 	/* integer arguments */
1704 #ifdef USE_PAM
1705 	dump_cfg_int(sUsePAM, o->use_pam);
1706 #endif
1707 	dump_cfg_int(sServerKeyBits, o->server_key_bits);
1708 	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1709 	dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1710 	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1711 	dump_cfg_int(sMaxAuthTries, o->max_authtries);
1712 	dump_cfg_int(sMaxSessions, o->max_sessions);
1713 	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1714 	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1715 
1716 	/* formatted integer arguments */
1717 	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1718 	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1719 	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1720 	dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1721 	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1722 	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1723 	    o->hostbased_uses_name_from_packet_only);
1724 	dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1725 	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1726 #ifdef KRB5
1727 	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1728 	dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1729 	dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1730 # ifdef USE_AFS
1731 	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1732 # endif
1733 #endif
1734 #ifdef GSSAPI
1735 	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1736 	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1737 #endif
1738 #ifdef JPAKE
1739 	dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
1740 	    o->zero_knowledge_password_authentication);
1741 #endif
1742 	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1743 	dump_cfg_fmtint(sKbdInteractiveAuthentication,
1744 	    o->kbd_interactive_authentication);
1745 	dump_cfg_fmtint(sChallengeResponseAuthentication,
1746 	    o->challenge_response_authentication);
1747 	dump_cfg_fmtint(sPrintMotd, o->print_motd);
1748 	dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1749 	dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1750 	dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1751 	dump_cfg_fmtint(sStrictModes, o->strict_modes);
1752 	dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1753 	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1754 	dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1755 	dump_cfg_fmtint(sUseLogin, o->use_login);
1756 	dump_cfg_fmtint(sCompression, o->compression);
1757 	dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1758 	dump_cfg_fmtint(sUseDNS, o->use_dns);
1759 	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1760 	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1761 
1762 	/* string arguments */
1763 	dump_cfg_string(sPidFile, o->pid_file);
1764 	dump_cfg_string(sXAuthLocation, o->xauth_location);
1765 	dump_cfg_string(sCiphers, o->ciphers);
1766 	dump_cfg_string(sMacs, o->macs);
1767 	dump_cfg_string(sBanner, o->banner);
1768 	dump_cfg_string(sForceCommand, o->adm_forced_command);
1769 	dump_cfg_string(sChrootDirectory, o->chroot_directory);
1770 	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
1771 	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1772 	dump_cfg_string(sAuthorizedPrincipalsFile,
1773 	    o->authorized_principals_file);
1774 
1775 	/* string arguments requiring a lookup */
1776 	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1777 	dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1778 
1779 	/* string array arguments */
1780 	dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
1781 	    o->authorized_keys_files);
1782 	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1783 	     o->host_key_files);
1784 	dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files,
1785 	     o->host_cert_files);
1786 	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1787 	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1788 	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1789 	dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1790 	dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1791 
1792 	/* other arguments */
1793 	for (i = 0; i < o->num_subsystems; i++)
1794 		printf("subsystem %s %s\n", o->subsystem_name[i],
1795 		    o->subsystem_args[i]);
1796 
1797 	printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1798 	    o->max_startups_rate, o->max_startups);
1799 
1800 	for (i = 0; tunmode_desc[i].val != -1; i++)
1801 		if (tunmode_desc[i].val == o->permit_tun) {
1802 			s = tunmode_desc[i].text;
1803 			break;
1804 		}
1805 	dump_cfg_string(sPermitTunnel, s);
1806 
1807 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
1808 	printf("%s\n", iptos2str(o->ip_qos_bulk));
1809 
1810 	channel_print_adm_permitted_opens();
1811 }
1812