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