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