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