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