1 /* $OpenBSD: readconf.c,v 1.218 2014/02/23 20:11:36 djm Exp $ */
2 /*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 * Functions for reading the configuration files.
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
13 */
14
15 #include "includes.h"
16 __RCSID("$FreeBSD$");
17
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/socket.h>
21 #include <sys/sysctl.h>
22 #include <sys/wait.h>
23
24 #include <netinet/in.h>
25 #include <netinet/in_systm.h>
26 #include <netinet/ip.h>
27 #include <arpa/inet.h>
28
29 #include <ctype.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <netdb.h>
33 #ifdef HAVE_PATHS_H
34 # include <paths.h>
35 #endif
36 #include <pwd.h>
37 #include <signal.h>
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <unistd.h>
42 #ifdef HAVE_UTIL_H
43 #include <util.h>
44 #endif
45
46 #include "xmalloc.h"
47 #include "ssh.h"
48 #include "compat.h"
49 #include "cipher.h"
50 #include "pathnames.h"
51 #include "log.h"
52 #include "key.h"
53 #include "readconf.h"
54 #include "match.h"
55 #include "misc.h"
56 #include "buffer.h"
57 #include "kex.h"
58 #include "mac.h"
59 #include "uidswap.h"
60 #include "version.h"
61
62 /* Format of the configuration file:
63
64 # Configuration data is parsed as follows:
65 # 1. command line options
66 # 2. user-specific file
67 # 3. system-wide file
68 # Any configuration value is only changed the first time it is set.
69 # Thus, host-specific definitions should be at the beginning of the
70 # configuration file, and defaults at the end.
71
72 # Host-specific declarations. These may override anything above. A single
73 # host may match multiple declarations; these are processed in the order
74 # that they are given in.
75
76 Host *.ngs.fi ngs.fi
77 User foo
78
79 Host fake.com
80 HostName another.host.name.real.org
81 User blaah
82 Port 34289
83 ForwardX11 no
84 ForwardAgent no
85
86 Host books.com
87 RemoteForward 9999 shadows.cs.hut.fi:9999
88 Cipher 3des
89
90 Host fascist.blob.com
91 Port 23123
92 User tylonen
93 PasswordAuthentication no
94
95 Host puukko.hut.fi
96 User t35124p
97 ProxyCommand ssh-proxy %h %p
98
99 Host *.fr
100 PublicKeyAuthentication no
101
102 Host *.su
103 Cipher none
104 PasswordAuthentication no
105
106 Host vpn.fake.com
107 Tunnel yes
108 TunnelDevice 3
109
110 # Defaults for various options
111 Host *
112 ForwardAgent no
113 ForwardX11 no
114 PasswordAuthentication yes
115 RSAAuthentication yes
116 RhostsRSAAuthentication yes
117 StrictHostKeyChecking yes
118 TcpKeepAlive no
119 IdentityFile ~/.ssh/identity
120 Port 22
121 EscapeChar ~
122
123 */
124
125 /* Keyword tokens. */
126
127 typedef enum {
128 oBadOption,
129 oHost, oMatch,
130 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
131 oGatewayPorts, oExitOnForwardFailure,
132 oPasswordAuthentication, oRSAAuthentication,
133 oChallengeResponseAuthentication, oXAuthLocation,
134 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
135 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
136 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
137 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
138 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
139 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
140 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
141 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
142 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
143 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
144 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
145 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
146 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
147 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
148 oSendEnv, oControlPath, oControlMaster, oControlPersist,
149 oHashKnownHosts,
150 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
151 oVisualHostKey, oUseRoaming,
152 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
153 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
154 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
155 oIgnoredUnknownOption,
156 oHPNDisabled, oHPNBufferSize, oTcpRcvBufPoll, oTcpRcvBuf,
157 oVersionAddendum, oDeprecated, oUnsupported
158 } OpCodes;
159
160 /* Textual representations of the tokens. */
161
162 static struct {
163 const char *name;
164 OpCodes opcode;
165 } keywords[] = {
166 { "forwardagent", oForwardAgent },
167 { "forwardx11", oForwardX11 },
168 { "forwardx11trusted", oForwardX11Trusted },
169 { "forwardx11timeout", oForwardX11Timeout },
170 { "exitonforwardfailure", oExitOnForwardFailure },
171 { "xauthlocation", oXAuthLocation },
172 { "gatewayports", oGatewayPorts },
173 { "useprivilegedport", oUsePrivilegedPort },
174 { "rhostsauthentication", oDeprecated },
175 { "passwordauthentication", oPasswordAuthentication },
176 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
177 { "kbdinteractivedevices", oKbdInteractiveDevices },
178 { "rsaauthentication", oRSAAuthentication },
179 { "pubkeyauthentication", oPubkeyAuthentication },
180 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
181 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
182 { "hostbasedauthentication", oHostbasedAuthentication },
183 { "challengeresponseauthentication", oChallengeResponseAuthentication },
184 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
185 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
186 { "kerberosauthentication", oUnsupported },
187 { "kerberostgtpassing", oUnsupported },
188 { "afstokenpassing", oUnsupported },
189 #if defined(GSSAPI)
190 { "gssapiauthentication", oGssAuthentication },
191 { "gssapidelegatecredentials", oGssDelegateCreds },
192 #else
193 { "gssapiauthentication", oUnsupported },
194 { "gssapidelegatecredentials", oUnsupported },
195 #endif
196 { "fallbacktorsh", oDeprecated },
197 { "usersh", oDeprecated },
198 { "identityfile", oIdentityFile },
199 { "identityfile2", oIdentityFile }, /* obsolete */
200 { "identitiesonly", oIdentitiesOnly },
201 { "hostname", oHostName },
202 { "hostkeyalias", oHostKeyAlias },
203 { "proxycommand", oProxyCommand },
204 { "port", oPort },
205 { "cipher", oCipher },
206 { "ciphers", oCiphers },
207 { "macs", oMacs },
208 { "protocol", oProtocol },
209 { "remoteforward", oRemoteForward },
210 { "localforward", oLocalForward },
211 { "user", oUser },
212 { "host", oHost },
213 { "match", oMatch },
214 { "escapechar", oEscapeChar },
215 { "globalknownhostsfile", oGlobalKnownHostsFile },
216 { "globalknownhostsfile2", oDeprecated },
217 { "userknownhostsfile", oUserKnownHostsFile },
218 { "userknownhostsfile2", oDeprecated },
219 { "connectionattempts", oConnectionAttempts },
220 { "batchmode", oBatchMode },
221 { "checkhostip", oCheckHostIP },
222 { "stricthostkeychecking", oStrictHostKeyChecking },
223 { "compression", oCompression },
224 { "compressionlevel", oCompressionLevel },
225 { "tcpkeepalive", oTCPKeepAlive },
226 { "keepalive", oTCPKeepAlive }, /* obsolete */
227 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
228 { "loglevel", oLogLevel },
229 { "dynamicforward", oDynamicForward },
230 { "preferredauthentications", oPreferredAuthentications },
231 { "hostkeyalgorithms", oHostKeyAlgorithms },
232 { "bindaddress", oBindAddress },
233 #ifdef ENABLE_PKCS11
234 { "smartcarddevice", oPKCS11Provider },
235 { "pkcs11provider", oPKCS11Provider },
236 #else
237 { "smartcarddevice", oUnsupported },
238 { "pkcs11provider", oUnsupported },
239 #endif
240 { "clearallforwardings", oClearAllForwardings },
241 { "enablesshkeysign", oEnableSSHKeysign },
242 { "verifyhostkeydns", oVerifyHostKeyDNS },
243 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
244 { "rekeylimit", oRekeyLimit },
245 { "connecttimeout", oConnectTimeout },
246 { "addressfamily", oAddressFamily },
247 { "serveraliveinterval", oServerAliveInterval },
248 { "serveralivecountmax", oServerAliveCountMax },
249 { "sendenv", oSendEnv },
250 { "controlpath", oControlPath },
251 { "controlmaster", oControlMaster },
252 { "controlpersist", oControlPersist },
253 { "hashknownhosts", oHashKnownHosts },
254 { "tunnel", oTunnel },
255 { "tunneldevice", oTunnelDevice },
256 { "localcommand", oLocalCommand },
257 { "permitlocalcommand", oPermitLocalCommand },
258 { "visualhostkey", oVisualHostKey },
259 { "useroaming", oUseRoaming },
260 { "kexalgorithms", oKexAlgorithms },
261 { "ipqos", oIPQoS },
262 { "requesttty", oRequestTTY },
263 { "proxyusefdpass", oProxyUseFdpass },
264 { "canonicaldomains", oCanonicalDomains },
265 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
266 { "canonicalizehostname", oCanonicalizeHostname },
267 { "canonicalizemaxdots", oCanonicalizeMaxDots },
268 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
269 { "ignoreunknown", oIgnoreUnknown },
270 { "hpndisabled", oHPNDisabled },
271 { "hpnbuffersize", oHPNBufferSize },
272 { "tcprcvbufpoll", oTcpRcvBufPoll },
273 { "tcprcvbuf", oTcpRcvBuf },
274 { "versionaddendum", oVersionAddendum },
275
276 { NULL, oBadOption }
277 };
278
279 /*
280 * Adds a local TCP/IP port forward to options. Never returns if there is an
281 * error.
282 */
283
284 void
add_local_forward(Options * options,const Forward * newfwd)285 add_local_forward(Options *options, const Forward *newfwd)
286 {
287 Forward *fwd;
288 #ifndef NO_IPPORT_RESERVED_CONCEPT
289 extern uid_t original_real_uid;
290 int ipport_reserved;
291 #ifdef __FreeBSD__
292 size_t len_ipport_reserved = sizeof(ipport_reserved);
293
294 if (sysctlbyname("net.inet.ip.portrange.reservedhigh",
295 &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0)
296 ipport_reserved = IPPORT_RESERVED;
297 else
298 ipport_reserved++;
299 #else
300 ipport_reserved = IPPORT_RESERVED;
301 #endif
302 if (newfwd->listen_port < ipport_reserved && original_real_uid != 0)
303 fatal("Privileged ports can only be forwarded by root.");
304 #endif
305 options->local_forwards = xrealloc(options->local_forwards,
306 options->num_local_forwards + 1,
307 sizeof(*options->local_forwards));
308 fwd = &options->local_forwards[options->num_local_forwards++];
309
310 fwd->listen_host = newfwd->listen_host;
311 fwd->listen_port = newfwd->listen_port;
312 fwd->connect_host = newfwd->connect_host;
313 fwd->connect_port = newfwd->connect_port;
314 }
315
316 /*
317 * Adds a remote TCP/IP port forward to options. Never returns if there is
318 * an error.
319 */
320
321 void
add_remote_forward(Options * options,const Forward * newfwd)322 add_remote_forward(Options *options, const Forward *newfwd)
323 {
324 Forward *fwd;
325
326 options->remote_forwards = xrealloc(options->remote_forwards,
327 options->num_remote_forwards + 1,
328 sizeof(*options->remote_forwards));
329 fwd = &options->remote_forwards[options->num_remote_forwards++];
330
331 fwd->listen_host = newfwd->listen_host;
332 fwd->listen_port = newfwd->listen_port;
333 fwd->connect_host = newfwd->connect_host;
334 fwd->connect_port = newfwd->connect_port;
335 fwd->handle = newfwd->handle;
336 fwd->allocated_port = 0;
337 }
338
339 static void
clear_forwardings(Options * options)340 clear_forwardings(Options *options)
341 {
342 int i;
343
344 for (i = 0; i < options->num_local_forwards; i++) {
345 free(options->local_forwards[i].listen_host);
346 free(options->local_forwards[i].connect_host);
347 }
348 if (options->num_local_forwards > 0) {
349 free(options->local_forwards);
350 options->local_forwards = NULL;
351 }
352 options->num_local_forwards = 0;
353 for (i = 0; i < options->num_remote_forwards; i++) {
354 free(options->remote_forwards[i].listen_host);
355 free(options->remote_forwards[i].connect_host);
356 }
357 if (options->num_remote_forwards > 0) {
358 free(options->remote_forwards);
359 options->remote_forwards = NULL;
360 }
361 options->num_remote_forwards = 0;
362 options->tun_open = SSH_TUNMODE_NO;
363 }
364
365 void
add_identity_file(Options * options,const char * dir,const char * filename,int userprovided)366 add_identity_file(Options *options, const char *dir, const char *filename,
367 int userprovided)
368 {
369 char *path;
370
371 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
372 fatal("Too many identity files specified (max %d)",
373 SSH_MAX_IDENTITY_FILES);
374
375 if (dir == NULL) /* no dir, filename is absolute */
376 path = xstrdup(filename);
377 else
378 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
379
380 options->identity_file_userprovided[options->num_identity_files] =
381 userprovided;
382 options->identity_files[options->num_identity_files++] = path;
383 }
384
385 int
default_ssh_port(void)386 default_ssh_port(void)
387 {
388 static int port;
389 struct servent *sp;
390
391 if (port == 0) {
392 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
393 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
394 }
395 return port;
396 }
397
398 /*
399 * Execute a command in a shell.
400 * Return its exit status or -1 on abnormal exit.
401 */
402 static int
execute_in_shell(const char * cmd)403 execute_in_shell(const char *cmd)
404 {
405 char *shell, *command_string;
406 pid_t pid;
407 int devnull, status;
408 extern uid_t original_real_uid;
409
410 if ((shell = getenv("SHELL")) == NULL)
411 shell = _PATH_BSHELL;
412
413 /*
414 * Use "exec" to avoid "sh -c" processes on some platforms
415 * (e.g. Solaris)
416 */
417 xasprintf(&command_string, "exec %s", cmd);
418
419 /* Need this to redirect subprocess stdin/out */
420 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
421 fatal("open(/dev/null): %s", strerror(errno));
422
423 debug("Executing command: '%.500s'", cmd);
424
425 /* Fork and execute the command. */
426 if ((pid = fork()) == 0) {
427 char *argv[4];
428
429 /* Child. Permanently give up superuser privileges. */
430 permanently_drop_suid(original_real_uid);
431
432 /* Redirect child stdin and stdout. Leave stderr */
433 if (dup2(devnull, STDIN_FILENO) == -1)
434 fatal("dup2: %s", strerror(errno));
435 if (dup2(devnull, STDOUT_FILENO) == -1)
436 fatal("dup2: %s", strerror(errno));
437 if (devnull > STDERR_FILENO)
438 close(devnull);
439 closefrom(STDERR_FILENO + 1);
440
441 argv[0] = shell;
442 argv[1] = "-c";
443 argv[2] = command_string;
444 argv[3] = NULL;
445
446 execv(argv[0], argv);
447 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
448 /* Die with signal to make this error apparent to parent. */
449 signal(SIGTERM, SIG_DFL);
450 kill(getpid(), SIGTERM);
451 _exit(1);
452 }
453 /* Parent. */
454 if (pid < 0)
455 fatal("%s: fork: %.100s", __func__, strerror(errno));
456
457 close(devnull);
458 free(command_string);
459
460 while (waitpid(pid, &status, 0) == -1) {
461 if (errno != EINTR && errno != EAGAIN)
462 fatal("%s: waitpid: %s", __func__, strerror(errno));
463 }
464 if (!WIFEXITED(status)) {
465 error("command '%.100s' exited abnormally", cmd);
466 return -1;
467 }
468 debug3("command returned status %d", WEXITSTATUS(status));
469 return WEXITSTATUS(status);
470 }
471
472 /*
473 * Parse and execute a Match directive.
474 */
475 static int
match_cfg_line(Options * options,char ** condition,struct passwd * pw,const char * host_arg,const char * filename,int linenum)476 match_cfg_line(Options *options, char **condition, struct passwd *pw,
477 const char *host_arg, const char *filename, int linenum)
478 {
479 char *arg, *attrib, *cmd, *cp = *condition, *host;
480 const char *ruser;
481 int r, port, result = 1, attributes = 0;
482 size_t len;
483 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
484
485 /*
486 * Configuration is likely to be incomplete at this point so we
487 * must be prepared to use default values.
488 */
489 port = options->port <= 0 ? default_ssh_port() : options->port;
490 ruser = options->user == NULL ? pw->pw_name : options->user;
491 if (options->hostname != NULL) {
492 /* NB. Please keep in sync with ssh.c:main() */
493 host = percent_expand(options->hostname,
494 "h", host_arg, (char *)NULL);
495 } else
496 host = xstrdup(host_arg);
497
498 debug3("checking match for '%s' host %s", cp, host);
499 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
500 attributes++;
501 if (strcasecmp(attrib, "all") == 0) {
502 if (attributes != 1 ||
503 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
504 error("'all' cannot be combined with other "
505 "Match attributes");
506 result = -1;
507 goto out;
508 }
509 *condition = cp;
510 result = 1;
511 goto out;
512 }
513 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
514 error("Missing Match criteria for %s", attrib);
515 result = -1;
516 goto out;
517 }
518 len = strlen(arg);
519 if (strcasecmp(attrib, "host") == 0) {
520 if (match_hostname(host, arg, len) != 1)
521 result = 0;
522 else
523 debug("%.200s line %d: matched 'Host %.100s' ",
524 filename, linenum, host);
525 } else if (strcasecmp(attrib, "originalhost") == 0) {
526 if (match_hostname(host_arg, arg, len) != 1)
527 result = 0;
528 else
529 debug("%.200s line %d: matched "
530 "'OriginalHost %.100s' ",
531 filename, linenum, host_arg);
532 } else if (strcasecmp(attrib, "user") == 0) {
533 if (match_pattern_list(ruser, arg, len, 0) != 1)
534 result = 0;
535 else
536 debug("%.200s line %d: matched 'User %.100s' ",
537 filename, linenum, ruser);
538 } else if (strcasecmp(attrib, "localuser") == 0) {
539 if (match_pattern_list(pw->pw_name, arg, len, 0) != 1)
540 result = 0;
541 else
542 debug("%.200s line %d: matched "
543 "'LocalUser %.100s' ",
544 filename, linenum, pw->pw_name);
545 } else if (strcasecmp(attrib, "exec") == 0) {
546 if (gethostname(thishost, sizeof(thishost)) == -1)
547 fatal("gethostname: %s", strerror(errno));
548 strlcpy(shorthost, thishost, sizeof(shorthost));
549 shorthost[strcspn(thishost, ".")] = '\0';
550 snprintf(portstr, sizeof(portstr), "%d", port);
551
552 cmd = percent_expand(arg,
553 "L", shorthost,
554 "d", pw->pw_dir,
555 "h", host,
556 "l", thishost,
557 "n", host_arg,
558 "p", portstr,
559 "r", ruser,
560 "u", pw->pw_name,
561 (char *)NULL);
562 if (result != 1) {
563 /* skip execution if prior predicate failed */
564 debug("%.200s line %d: skipped exec \"%.100s\"",
565 filename, linenum, cmd);
566 } else {
567 r = execute_in_shell(cmd);
568 if (r == -1) {
569 fatal("%.200s line %d: match exec "
570 "'%.100s' error", filename,
571 linenum, cmd);
572 } else if (r == 0) {
573 debug("%.200s line %d: matched "
574 "'exec \"%.100s\"'", filename,
575 linenum, cmd);
576 } else {
577 debug("%.200s line %d: no match "
578 "'exec \"%.100s\"'", filename,
579 linenum, cmd);
580 result = 0;
581 }
582 }
583 free(cmd);
584 } else {
585 error("Unsupported Match attribute %s", attrib);
586 result = -1;
587 goto out;
588 }
589 }
590 if (attributes == 0) {
591 error("One or more attributes required for Match");
592 result = -1;
593 goto out;
594 }
595 debug3("match %sfound", result ? "" : "not ");
596 *condition = cp;
597 out:
598 free(host);
599 return result;
600 }
601
602 /* Check and prepare a domain name: removes trailing '.' and lowercases */
603 static void
valid_domain(char * name,const char * filename,int linenum)604 valid_domain(char *name, const char *filename, int linenum)
605 {
606 size_t i, l = strlen(name);
607 u_char c, last = '\0';
608
609 if (l == 0)
610 fatal("%s line %d: empty hostname suffix", filename, linenum);
611 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
612 fatal("%s line %d: hostname suffix \"%.100s\" "
613 "starts with invalid character", filename, linenum, name);
614 for (i = 0; i < l; i++) {
615 c = tolower((u_char)name[i]);
616 name[i] = (char)c;
617 if (last == '.' && c == '.')
618 fatal("%s line %d: hostname suffix \"%.100s\" contains "
619 "consecutive separators", filename, linenum, name);
620 if (c != '.' && c != '-' && !isalnum(c) &&
621 c != '_') /* technically invalid, but common */
622 fatal("%s line %d: hostname suffix \"%.100s\" contains "
623 "invalid characters", filename, linenum, name);
624 last = c;
625 }
626 if (name[l - 1] == '.')
627 name[l - 1] = '\0';
628 }
629
630 /*
631 * Returns the number of the token pointed to by cp or oBadOption.
632 */
633 static OpCodes
parse_token(const char * cp,const char * filename,int linenum,const char * ignored_unknown)634 parse_token(const char *cp, const char *filename, int linenum,
635 const char *ignored_unknown)
636 {
637 int i;
638
639 for (i = 0; keywords[i].name; i++)
640 if (strcmp(cp, keywords[i].name) == 0)
641 return keywords[i].opcode;
642 if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
643 strlen(ignored_unknown), 1) == 1)
644 return oIgnoredUnknownOption;
645 error("%s: line %d: Bad configuration option: %s",
646 filename, linenum, cp);
647 return oBadOption;
648 }
649
650 /* Multistate option parsing */
651 struct multistate {
652 char *key;
653 int value;
654 };
655 static const struct multistate multistate_flag[] = {
656 { "true", 1 },
657 { "false", 0 },
658 { "yes", 1 },
659 { "no", 0 },
660 { NULL, -1 }
661 };
662 static const struct multistate multistate_yesnoask[] = {
663 { "true", 1 },
664 { "false", 0 },
665 { "yes", 1 },
666 { "no", 0 },
667 { "ask", 2 },
668 { NULL, -1 }
669 };
670 static const struct multistate multistate_addressfamily[] = {
671 { "inet", AF_INET },
672 { "inet6", AF_INET6 },
673 { "any", AF_UNSPEC },
674 { NULL, -1 }
675 };
676 static const struct multistate multistate_controlmaster[] = {
677 { "true", SSHCTL_MASTER_YES },
678 { "yes", SSHCTL_MASTER_YES },
679 { "false", SSHCTL_MASTER_NO },
680 { "no", SSHCTL_MASTER_NO },
681 { "auto", SSHCTL_MASTER_AUTO },
682 { "ask", SSHCTL_MASTER_ASK },
683 { "autoask", SSHCTL_MASTER_AUTO_ASK },
684 { NULL, -1 }
685 };
686 static const struct multistate multistate_tunnel[] = {
687 { "ethernet", SSH_TUNMODE_ETHERNET },
688 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
689 { "true", SSH_TUNMODE_DEFAULT },
690 { "yes", SSH_TUNMODE_DEFAULT },
691 { "false", SSH_TUNMODE_NO },
692 { "no", SSH_TUNMODE_NO },
693 { NULL, -1 }
694 };
695 static const struct multistate multistate_requesttty[] = {
696 { "true", REQUEST_TTY_YES },
697 { "yes", REQUEST_TTY_YES },
698 { "false", REQUEST_TTY_NO },
699 { "no", REQUEST_TTY_NO },
700 { "force", REQUEST_TTY_FORCE },
701 { "auto", REQUEST_TTY_AUTO },
702 { NULL, -1 }
703 };
704 static const struct multistate multistate_canonicalizehostname[] = {
705 { "true", SSH_CANONICALISE_YES },
706 { "false", SSH_CANONICALISE_NO },
707 { "yes", SSH_CANONICALISE_YES },
708 { "no", SSH_CANONICALISE_NO },
709 { "always", SSH_CANONICALISE_ALWAYS },
710 { NULL, -1 }
711 };
712
713 /*
714 * Processes a single option line as used in the configuration files. This
715 * only sets those values that have not already been set.
716 */
717 #define WHITESPACE " \t\r\n"
718 int
process_config_line(Options * options,struct passwd * pw,const char * host,char * line,const char * filename,int linenum,int * activep,int userconfig)719 process_config_line(Options *options, struct passwd *pw, const char *host,
720 char *line, const char *filename, int linenum, int *activep, int userconfig)
721 {
722 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
723 char **cpptr, fwdarg[256];
724 u_int i, *uintptr, max_entries = 0;
725 int negated, opcode, *intptr, value, value2, cmdline = 0;
726 LogLevel *log_level_ptr;
727 long long val64;
728 size_t len;
729 Forward fwd;
730 const struct multistate *multistate_ptr;
731 struct allowed_cname *cname;
732
733 if (activep == NULL) { /* We are processing a command line directive */
734 cmdline = 1;
735 activep = &cmdline;
736 }
737
738 /* Strip trailing whitespace */
739 for (len = strlen(line) - 1; len > 0; len--) {
740 if (strchr(WHITESPACE, line[len]) == NULL)
741 break;
742 line[len] = '\0';
743 }
744
745 s = line;
746 /* Get the keyword. (Each line is supposed to begin with a keyword). */
747 if ((keyword = strdelim(&s)) == NULL)
748 return 0;
749 /* Ignore leading whitespace. */
750 if (*keyword == '\0')
751 keyword = strdelim(&s);
752 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
753 return 0;
754 /* Match lowercase keyword */
755 lowercase(keyword);
756
757 opcode = parse_token(keyword, filename, linenum,
758 options->ignored_unknown);
759
760 switch (opcode) {
761 case oBadOption:
762 /* don't panic, but count bad options */
763 return -1;
764 /* NOTREACHED */
765 case oIgnoredUnknownOption:
766 debug("%s line %d: Ignored unknown option \"%s\"",
767 filename, linenum, keyword);
768 return 0;
769 case oConnectTimeout:
770 intptr = &options->connection_timeout;
771 parse_time:
772 arg = strdelim(&s);
773 if (!arg || *arg == '\0')
774 fatal("%s line %d: missing time value.",
775 filename, linenum);
776 if ((value = convtime(arg)) == -1)
777 fatal("%s line %d: invalid time value.",
778 filename, linenum);
779 if (*activep && *intptr == -1)
780 *intptr = value;
781 break;
782
783 case oForwardAgent:
784 intptr = &options->forward_agent;
785 parse_flag:
786 multistate_ptr = multistate_flag;
787 parse_multistate:
788 arg = strdelim(&s);
789 if (!arg || *arg == '\0')
790 fatal("%s line %d: missing argument.",
791 filename, linenum);
792 value = -1;
793 for (i = 0; multistate_ptr[i].key != NULL; i++) {
794 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
795 value = multistate_ptr[i].value;
796 break;
797 }
798 }
799 if (value == -1)
800 fatal("%s line %d: unsupported option \"%s\".",
801 filename, linenum, arg);
802 if (*activep && *intptr == -1)
803 *intptr = value;
804 break;
805
806 case oForwardX11:
807 intptr = &options->forward_x11;
808 goto parse_flag;
809
810 case oForwardX11Trusted:
811 intptr = &options->forward_x11_trusted;
812 goto parse_flag;
813
814 case oForwardX11Timeout:
815 intptr = &options->forward_x11_timeout;
816 goto parse_time;
817
818 case oGatewayPorts:
819 intptr = &options->gateway_ports;
820 goto parse_flag;
821
822 case oExitOnForwardFailure:
823 intptr = &options->exit_on_forward_failure;
824 goto parse_flag;
825
826 case oUsePrivilegedPort:
827 intptr = &options->use_privileged_port;
828 goto parse_flag;
829
830 case oPasswordAuthentication:
831 intptr = &options->password_authentication;
832 goto parse_flag;
833
834 case oKbdInteractiveAuthentication:
835 intptr = &options->kbd_interactive_authentication;
836 goto parse_flag;
837
838 case oKbdInteractiveDevices:
839 charptr = &options->kbd_interactive_devices;
840 goto parse_string;
841
842 case oPubkeyAuthentication:
843 intptr = &options->pubkey_authentication;
844 goto parse_flag;
845
846 case oRSAAuthentication:
847 intptr = &options->rsa_authentication;
848 goto parse_flag;
849
850 case oRhostsRSAAuthentication:
851 intptr = &options->rhosts_rsa_authentication;
852 goto parse_flag;
853
854 case oHostbasedAuthentication:
855 intptr = &options->hostbased_authentication;
856 goto parse_flag;
857
858 case oChallengeResponseAuthentication:
859 intptr = &options->challenge_response_authentication;
860 goto parse_flag;
861
862 case oGssAuthentication:
863 intptr = &options->gss_authentication;
864 goto parse_flag;
865
866 case oGssDelegateCreds:
867 intptr = &options->gss_deleg_creds;
868 goto parse_flag;
869
870 case oBatchMode:
871 intptr = &options->batch_mode;
872 goto parse_flag;
873
874 case oCheckHostIP:
875 intptr = &options->check_host_ip;
876 goto parse_flag;
877
878 case oVerifyHostKeyDNS:
879 intptr = &options->verify_host_key_dns;
880 multistate_ptr = multistate_yesnoask;
881 goto parse_multistate;
882
883 case oStrictHostKeyChecking:
884 intptr = &options->strict_host_key_checking;
885 multistate_ptr = multistate_yesnoask;
886 goto parse_multistate;
887
888 case oCompression:
889 intptr = &options->compression;
890 goto parse_flag;
891
892 case oTCPKeepAlive:
893 intptr = &options->tcp_keep_alive;
894 goto parse_flag;
895
896 case oNoHostAuthenticationForLocalhost:
897 intptr = &options->no_host_authentication_for_localhost;
898 goto parse_flag;
899
900 case oNumberOfPasswordPrompts:
901 intptr = &options->number_of_password_prompts;
902 goto parse_int;
903
904 case oCompressionLevel:
905 intptr = &options->compression_level;
906 goto parse_int;
907
908 case oRekeyLimit:
909 arg = strdelim(&s);
910 if (!arg || *arg == '\0')
911 fatal("%.200s line %d: Missing argument.", filename,
912 linenum);
913 if (strcmp(arg, "default") == 0) {
914 val64 = 0;
915 } else {
916 if (scan_scaled(arg, &val64) == -1)
917 fatal("%.200s line %d: Bad number '%s': %s",
918 filename, linenum, arg, strerror(errno));
919 /* check for too-large or too-small limits */
920 if (val64 > UINT_MAX)
921 fatal("%.200s line %d: RekeyLimit too large",
922 filename, linenum);
923 if (val64 != 0 && val64 < 16)
924 fatal("%.200s line %d: RekeyLimit too small",
925 filename, linenum);
926 }
927 if (*activep && options->rekey_limit == -1)
928 options->rekey_limit = (u_int32_t)val64;
929 if (s != NULL) { /* optional rekey interval present */
930 if (strcmp(s, "none") == 0) {
931 (void)strdelim(&s); /* discard */
932 break;
933 }
934 intptr = &options->rekey_interval;
935 goto parse_time;
936 }
937 break;
938
939 case oIdentityFile:
940 arg = strdelim(&s);
941 if (!arg || *arg == '\0')
942 fatal("%.200s line %d: Missing argument.", filename, linenum);
943 if (*activep) {
944 intptr = &options->num_identity_files;
945 if (*intptr >= SSH_MAX_IDENTITY_FILES)
946 fatal("%.200s line %d: Too many identity files specified (max %d).",
947 filename, linenum, SSH_MAX_IDENTITY_FILES);
948 add_identity_file(options, NULL, arg, userconfig);
949 }
950 break;
951
952 case oXAuthLocation:
953 charptr=&options->xauth_location;
954 goto parse_string;
955
956 case oUser:
957 charptr = &options->user;
958 parse_string:
959 arg = strdelim(&s);
960 if (!arg || *arg == '\0')
961 fatal("%.200s line %d: Missing argument.",
962 filename, linenum);
963 if (*activep && *charptr == NULL)
964 *charptr = xstrdup(arg);
965 break;
966
967 case oGlobalKnownHostsFile:
968 cpptr = (char **)&options->system_hostfiles;
969 uintptr = &options->num_system_hostfiles;
970 max_entries = SSH_MAX_HOSTS_FILES;
971 parse_char_array:
972 if (*activep && *uintptr == 0) {
973 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
974 if ((*uintptr) >= max_entries)
975 fatal("%s line %d: "
976 "too many authorized keys files.",
977 filename, linenum);
978 cpptr[(*uintptr)++] = xstrdup(arg);
979 }
980 }
981 return 0;
982
983 case oUserKnownHostsFile:
984 cpptr = (char **)&options->user_hostfiles;
985 uintptr = &options->num_user_hostfiles;
986 max_entries = SSH_MAX_HOSTS_FILES;
987 goto parse_char_array;
988
989 case oHostName:
990 charptr = &options->hostname;
991 goto parse_string;
992
993 case oHostKeyAlias:
994 charptr = &options->host_key_alias;
995 goto parse_string;
996
997 case oPreferredAuthentications:
998 charptr = &options->preferred_authentications;
999 goto parse_string;
1000
1001 case oBindAddress:
1002 charptr = &options->bind_address;
1003 goto parse_string;
1004
1005 case oPKCS11Provider:
1006 charptr = &options->pkcs11_provider;
1007 goto parse_string;
1008
1009 case oProxyCommand:
1010 charptr = &options->proxy_command;
1011 parse_command:
1012 if (s == NULL)
1013 fatal("%.200s line %d: Missing argument.", filename, linenum);
1014 len = strspn(s, WHITESPACE "=");
1015 if (*activep && *charptr == NULL)
1016 *charptr = xstrdup(s + len);
1017 return 0;
1018
1019 case oPort:
1020 intptr = &options->port;
1021 parse_int:
1022 arg = strdelim(&s);
1023 if (!arg || *arg == '\0')
1024 fatal("%.200s line %d: Missing argument.", filename, linenum);
1025 if (arg[0] < '0' || arg[0] > '9')
1026 fatal("%.200s line %d: Bad number.", filename, linenum);
1027
1028 /* Octal, decimal, or hex format? */
1029 value = strtol(arg, &endofnumber, 0);
1030 if (arg == endofnumber)
1031 fatal("%.200s line %d: Bad number.", filename, linenum);
1032 if (*activep && *intptr == -1)
1033 *intptr = value;
1034 break;
1035
1036 case oConnectionAttempts:
1037 intptr = &options->connection_attempts;
1038 goto parse_int;
1039
1040 case oCipher:
1041 intptr = &options->cipher;
1042 arg = strdelim(&s);
1043 if (!arg || *arg == '\0')
1044 fatal("%.200s line %d: Missing argument.", filename, linenum);
1045 value = cipher_number(arg);
1046 if (value == -1)
1047 fatal("%.200s line %d: Bad cipher '%s'.",
1048 filename, linenum, arg ? arg : "<NONE>");
1049 if (*activep && *intptr == -1)
1050 *intptr = value;
1051 break;
1052
1053 case oCiphers:
1054 arg = strdelim(&s);
1055 if (!arg || *arg == '\0')
1056 fatal("%.200s line %d: Missing argument.", filename, linenum);
1057 if (!ciphers_valid(arg))
1058 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1059 filename, linenum, arg ? arg : "<NONE>");
1060 if (*activep && options->ciphers == NULL)
1061 options->ciphers = xstrdup(arg);
1062 break;
1063
1064 case oMacs:
1065 arg = strdelim(&s);
1066 if (!arg || *arg == '\0')
1067 fatal("%.200s line %d: Missing argument.", filename, linenum);
1068 if (!mac_valid(arg))
1069 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1070 filename, linenum, arg ? arg : "<NONE>");
1071 if (*activep && options->macs == NULL)
1072 options->macs = xstrdup(arg);
1073 break;
1074
1075 case oKexAlgorithms:
1076 arg = strdelim(&s);
1077 if (!arg || *arg == '\0')
1078 fatal("%.200s line %d: Missing argument.",
1079 filename, linenum);
1080 if (!kex_names_valid(arg))
1081 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1082 filename, linenum, arg ? arg : "<NONE>");
1083 if (*activep && options->kex_algorithms == NULL)
1084 options->kex_algorithms = xstrdup(arg);
1085 break;
1086
1087 case oHostKeyAlgorithms:
1088 arg = strdelim(&s);
1089 if (!arg || *arg == '\0')
1090 fatal("%.200s line %d: Missing argument.", filename, linenum);
1091 if (!key_names_valid2(arg))
1092 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
1093 filename, linenum, arg ? arg : "<NONE>");
1094 if (*activep && options->hostkeyalgorithms == NULL)
1095 options->hostkeyalgorithms = xstrdup(arg);
1096 break;
1097
1098 case oProtocol:
1099 intptr = &options->protocol;
1100 arg = strdelim(&s);
1101 if (!arg || *arg == '\0')
1102 fatal("%.200s line %d: Missing argument.", filename, linenum);
1103 value = proto_spec(arg);
1104 if (value == SSH_PROTO_UNKNOWN)
1105 fatal("%.200s line %d: Bad protocol spec '%s'.",
1106 filename, linenum, arg ? arg : "<NONE>");
1107 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1108 *intptr = value;
1109 break;
1110
1111 case oLogLevel:
1112 log_level_ptr = &options->log_level;
1113 arg = strdelim(&s);
1114 value = log_level_number(arg);
1115 if (value == SYSLOG_LEVEL_NOT_SET)
1116 fatal("%.200s line %d: unsupported log level '%s'",
1117 filename, linenum, arg ? arg : "<NONE>");
1118 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1119 *log_level_ptr = (LogLevel) value;
1120 break;
1121
1122 case oLocalForward:
1123 case oRemoteForward:
1124 case oDynamicForward:
1125 arg = strdelim(&s);
1126 if (arg == NULL || *arg == '\0')
1127 fatal("%.200s line %d: Missing port argument.",
1128 filename, linenum);
1129
1130 if (opcode == oLocalForward ||
1131 opcode == oRemoteForward) {
1132 arg2 = strdelim(&s);
1133 if (arg2 == NULL || *arg2 == '\0')
1134 fatal("%.200s line %d: Missing target argument.",
1135 filename, linenum);
1136
1137 /* construct a string for parse_forward */
1138 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1139 } else if (opcode == oDynamicForward) {
1140 strlcpy(fwdarg, arg, sizeof(fwdarg));
1141 }
1142
1143 if (parse_forward(&fwd, fwdarg,
1144 opcode == oDynamicForward ? 1 : 0,
1145 opcode == oRemoteForward ? 1 : 0) == 0)
1146 fatal("%.200s line %d: Bad forwarding specification.",
1147 filename, linenum);
1148
1149 if (*activep) {
1150 if (opcode == oLocalForward ||
1151 opcode == oDynamicForward)
1152 add_local_forward(options, &fwd);
1153 else if (opcode == oRemoteForward)
1154 add_remote_forward(options, &fwd);
1155 }
1156 break;
1157
1158 case oClearAllForwardings:
1159 intptr = &options->clear_forwardings;
1160 goto parse_flag;
1161
1162 case oHost:
1163 if (cmdline)
1164 fatal("Host directive not supported as a command-line "
1165 "option");
1166 *activep = 0;
1167 arg2 = NULL;
1168 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1169 negated = *arg == '!';
1170 if (negated)
1171 arg++;
1172 if (match_pattern(host, arg)) {
1173 if (negated) {
1174 debug("%.200s line %d: Skipping Host "
1175 "block because of negated match "
1176 "for %.100s", filename, linenum,
1177 arg);
1178 *activep = 0;
1179 break;
1180 }
1181 if (!*activep)
1182 arg2 = arg; /* logged below */
1183 *activep = 1;
1184 }
1185 }
1186 if (*activep)
1187 debug("%.200s line %d: Applying options for %.100s",
1188 filename, linenum, arg2);
1189 /* Avoid garbage check below, as strdelim is done. */
1190 return 0;
1191
1192 case oMatch:
1193 if (cmdline)
1194 fatal("Host directive not supported as a command-line "
1195 "option");
1196 value = match_cfg_line(options, &s, pw, host,
1197 filename, linenum);
1198 if (value < 0)
1199 fatal("%.200s line %d: Bad Match condition", filename,
1200 linenum);
1201 *activep = value;
1202 break;
1203
1204 case oEscapeChar:
1205 intptr = &options->escape_char;
1206 arg = strdelim(&s);
1207 if (!arg || *arg == '\0')
1208 fatal("%.200s line %d: Missing argument.", filename, linenum);
1209 if (arg[0] == '^' && arg[2] == 0 &&
1210 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1211 value = (u_char) arg[1] & 31;
1212 else if (strlen(arg) == 1)
1213 value = (u_char) arg[0];
1214 else if (strcmp(arg, "none") == 0)
1215 value = SSH_ESCAPECHAR_NONE;
1216 else {
1217 fatal("%.200s line %d: Bad escape character.",
1218 filename, linenum);
1219 /* NOTREACHED */
1220 value = 0; /* Avoid compiler warning. */
1221 }
1222 if (*activep && *intptr == -1)
1223 *intptr = value;
1224 break;
1225
1226 case oAddressFamily:
1227 intptr = &options->address_family;
1228 multistate_ptr = multistate_addressfamily;
1229 goto parse_multistate;
1230
1231 case oEnableSSHKeysign:
1232 intptr = &options->enable_ssh_keysign;
1233 goto parse_flag;
1234
1235 case oIdentitiesOnly:
1236 intptr = &options->identities_only;
1237 goto parse_flag;
1238
1239 case oServerAliveInterval:
1240 intptr = &options->server_alive_interval;
1241 goto parse_time;
1242
1243 case oServerAliveCountMax:
1244 intptr = &options->server_alive_count_max;
1245 goto parse_int;
1246
1247 case oSendEnv:
1248 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1249 if (strchr(arg, '=') != NULL)
1250 fatal("%s line %d: Invalid environment name.",
1251 filename, linenum);
1252 if (!*activep)
1253 continue;
1254 if (options->num_send_env >= MAX_SEND_ENV)
1255 fatal("%s line %d: too many send env.",
1256 filename, linenum);
1257 options->send_env[options->num_send_env++] =
1258 xstrdup(arg);
1259 }
1260 break;
1261
1262 case oControlPath:
1263 charptr = &options->control_path;
1264 goto parse_string;
1265
1266 case oControlMaster:
1267 intptr = &options->control_master;
1268 multistate_ptr = multistate_controlmaster;
1269 goto parse_multistate;
1270
1271 case oControlPersist:
1272 /* no/false/yes/true, or a time spec */
1273 intptr = &options->control_persist;
1274 arg = strdelim(&s);
1275 if (!arg || *arg == '\0')
1276 fatal("%.200s line %d: Missing ControlPersist"
1277 " argument.", filename, linenum);
1278 value = 0;
1279 value2 = 0; /* timeout */
1280 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1281 value = 0;
1282 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1283 value = 1;
1284 else if ((value2 = convtime(arg)) >= 0)
1285 value = 1;
1286 else
1287 fatal("%.200s line %d: Bad ControlPersist argument.",
1288 filename, linenum);
1289 if (*activep && *intptr == -1) {
1290 *intptr = value;
1291 options->control_persist_timeout = value2;
1292 }
1293 break;
1294
1295 case oHashKnownHosts:
1296 intptr = &options->hash_known_hosts;
1297 goto parse_flag;
1298
1299 case oTunnel:
1300 intptr = &options->tun_open;
1301 multistate_ptr = multistate_tunnel;
1302 goto parse_multistate;
1303
1304 case oTunnelDevice:
1305 arg = strdelim(&s);
1306 if (!arg || *arg == '\0')
1307 fatal("%.200s line %d: Missing argument.", filename, linenum);
1308 value = a2tun(arg, &value2);
1309 if (value == SSH_TUNID_ERR)
1310 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1311 if (*activep) {
1312 options->tun_local = value;
1313 options->tun_remote = value2;
1314 }
1315 break;
1316
1317 case oLocalCommand:
1318 charptr = &options->local_command;
1319 goto parse_command;
1320
1321 case oPermitLocalCommand:
1322 intptr = &options->permit_local_command;
1323 goto parse_flag;
1324
1325 case oVisualHostKey:
1326 intptr = &options->visual_host_key;
1327 goto parse_flag;
1328
1329 case oIPQoS:
1330 arg = strdelim(&s);
1331 if ((value = parse_ipqos(arg)) == -1)
1332 fatal("%s line %d: Bad IPQoS value: %s",
1333 filename, linenum, arg);
1334 arg = strdelim(&s);
1335 if (arg == NULL)
1336 value2 = value;
1337 else if ((value2 = parse_ipqos(arg)) == -1)
1338 fatal("%s line %d: Bad IPQoS value: %s",
1339 filename, linenum, arg);
1340 if (*activep) {
1341 options->ip_qos_interactive = value;
1342 options->ip_qos_bulk = value2;
1343 }
1344 break;
1345
1346 case oUseRoaming:
1347 intptr = &options->use_roaming;
1348 goto parse_flag;
1349
1350 case oRequestTTY:
1351 intptr = &options->request_tty;
1352 multistate_ptr = multistate_requesttty;
1353 goto parse_multistate;
1354
1355 case oHPNDisabled:
1356 intptr = &options->hpn_disabled;
1357 goto parse_flag;
1358
1359 case oHPNBufferSize:
1360 intptr = &options->hpn_buffer_size;
1361 goto parse_int;
1362
1363 case oTcpRcvBufPoll:
1364 intptr = &options->tcp_rcv_buf_poll;
1365 goto parse_flag;
1366
1367 case oTcpRcvBuf:
1368 intptr = &options->tcp_rcv_buf;
1369 goto parse_int;
1370
1371 case oVersionAddendum:
1372 if (s == NULL)
1373 fatal("%.200s line %d: Missing argument.", filename,
1374 linenum);
1375 len = strspn(s, WHITESPACE);
1376 if (*activep && options->version_addendum == NULL) {
1377 if (strcasecmp(s + len, "none") == 0)
1378 options->version_addendum = xstrdup("");
1379 else if (strchr(s + len, '\r') != NULL)
1380 fatal("%.200s line %d: Invalid argument",
1381 filename, linenum);
1382 else
1383 options->version_addendum = xstrdup(s + len);
1384 }
1385 return 0;
1386
1387 case oIgnoreUnknown:
1388 charptr = &options->ignored_unknown;
1389 goto parse_string;
1390
1391 case oProxyUseFdpass:
1392 intptr = &options->proxy_use_fdpass;
1393 goto parse_flag;
1394
1395 case oCanonicalDomains:
1396 value = options->num_canonical_domains != 0;
1397 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1398 valid_domain(arg, filename, linenum);
1399 if (!*activep || value)
1400 continue;
1401 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1402 fatal("%s line %d: too many hostname suffixes.",
1403 filename, linenum);
1404 options->canonical_domains[
1405 options->num_canonical_domains++] = xstrdup(arg);
1406 }
1407 break;
1408
1409 case oCanonicalizePermittedCNAMEs:
1410 value = options->num_permitted_cnames != 0;
1411 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1412 /* Either '*' for everything or 'list:list' */
1413 if (strcmp(arg, "*") == 0)
1414 arg2 = arg;
1415 else {
1416 lowercase(arg);
1417 if ((arg2 = strchr(arg, ':')) == NULL ||
1418 arg2[1] == '\0') {
1419 fatal("%s line %d: "
1420 "Invalid permitted CNAME \"%s\"",
1421 filename, linenum, arg);
1422 }
1423 *arg2 = '\0';
1424 arg2++;
1425 }
1426 if (!*activep || value)
1427 continue;
1428 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1429 fatal("%s line %d: too many permitted CNAMEs.",
1430 filename, linenum);
1431 cname = options->permitted_cnames +
1432 options->num_permitted_cnames++;
1433 cname->source_list = xstrdup(arg);
1434 cname->target_list = xstrdup(arg2);
1435 }
1436 break;
1437
1438 case oCanonicalizeHostname:
1439 intptr = &options->canonicalize_hostname;
1440 multistate_ptr = multistate_canonicalizehostname;
1441 goto parse_multistate;
1442
1443 case oCanonicalizeMaxDots:
1444 intptr = &options->canonicalize_max_dots;
1445 goto parse_int;
1446
1447 case oCanonicalizeFallbackLocal:
1448 intptr = &options->canonicalize_fallback_local;
1449 goto parse_flag;
1450
1451 case oDeprecated:
1452 debug("%s line %d: Deprecated option \"%s\"",
1453 filename, linenum, keyword);
1454 return 0;
1455
1456 case oUnsupported:
1457 error("%s line %d: Unsupported option \"%s\"",
1458 filename, linenum, keyword);
1459 return 0;
1460
1461 default:
1462 fatal("process_config_line: Unimplemented opcode %d", opcode);
1463 }
1464
1465 /* Check that there is no garbage at end of line. */
1466 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1467 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1468 filename, linenum, arg);
1469 }
1470 return 0;
1471 }
1472
1473
1474 /*
1475 * Reads the config file and modifies the options accordingly. Options
1476 * should already be initialized before this call. This never returns if
1477 * there is an error. If the file does not exist, this returns 0.
1478 */
1479
1480 int
read_config_file(const char * filename,struct passwd * pw,const char * host,Options * options,int flags)1481 read_config_file(const char *filename, struct passwd *pw, const char *host,
1482 Options *options, int flags)
1483 {
1484 FILE *f;
1485 char line[1024];
1486 int active, linenum;
1487 int bad_options = 0;
1488
1489 if ((f = fopen(filename, "r")) == NULL)
1490 return 0;
1491
1492 if (flags & SSHCONF_CHECKPERM) {
1493 struct stat sb;
1494
1495 if (fstat(fileno(f), &sb) == -1)
1496 fatal("fstat %s: %s", filename, strerror(errno));
1497 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1498 (sb.st_mode & 022) != 0))
1499 fatal("Bad owner or permissions on %s", filename);
1500 }
1501
1502 debug("Reading configuration data %.200s", filename);
1503
1504 /*
1505 * Mark that we are now processing the options. This flag is turned
1506 * on/off by Host specifications.
1507 */
1508 active = 1;
1509 linenum = 0;
1510 while (fgets(line, sizeof(line), f)) {
1511 /* Update line number counter. */
1512 linenum++;
1513 if (process_config_line(options, pw, host, line, filename,
1514 linenum, &active, flags & SSHCONF_USERCONF) != 0)
1515 bad_options++;
1516 }
1517 fclose(f);
1518 if (bad_options > 0)
1519 fatal("%s: terminating, %d bad configuration options",
1520 filename, bad_options);
1521 return 1;
1522 }
1523
1524 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1525 int
option_clear_or_none(const char * o)1526 option_clear_or_none(const char *o)
1527 {
1528 return o == NULL || strcasecmp(o, "none") == 0;
1529 }
1530
1531 /*
1532 * Initializes options to special values that indicate that they have not yet
1533 * been set. Read_config_file will only set options with this value. Options
1534 * are processed in the following order: command line, user config file,
1535 * system config file. Last, fill_default_options is called.
1536 */
1537
1538 void
initialize_options(Options * options)1539 initialize_options(Options * options)
1540 {
1541 memset(options, 'X', sizeof(*options));
1542 options->forward_agent = -1;
1543 options->forward_x11 = -1;
1544 options->forward_x11_trusted = -1;
1545 options->forward_x11_timeout = -1;
1546 options->exit_on_forward_failure = -1;
1547 options->xauth_location = NULL;
1548 options->gateway_ports = -1;
1549 options->use_privileged_port = -1;
1550 options->rsa_authentication = -1;
1551 options->pubkey_authentication = -1;
1552 options->challenge_response_authentication = -1;
1553 options->gss_authentication = -1;
1554 options->gss_deleg_creds = -1;
1555 options->password_authentication = -1;
1556 options->kbd_interactive_authentication = -1;
1557 options->kbd_interactive_devices = NULL;
1558 options->rhosts_rsa_authentication = -1;
1559 options->hostbased_authentication = -1;
1560 options->batch_mode = -1;
1561 options->check_host_ip = -1;
1562 options->strict_host_key_checking = -1;
1563 options->compression = -1;
1564 options->tcp_keep_alive = -1;
1565 options->compression_level = -1;
1566 options->port = -1;
1567 options->address_family = -1;
1568 options->connection_attempts = -1;
1569 options->connection_timeout = -1;
1570 options->number_of_password_prompts = -1;
1571 options->cipher = -1;
1572 options->ciphers = NULL;
1573 options->macs = NULL;
1574 options->kex_algorithms = NULL;
1575 options->hostkeyalgorithms = NULL;
1576 options->protocol = SSH_PROTO_UNKNOWN;
1577 options->num_identity_files = 0;
1578 options->hostname = NULL;
1579 options->host_key_alias = NULL;
1580 options->proxy_command = NULL;
1581 options->user = NULL;
1582 options->escape_char = -1;
1583 options->num_system_hostfiles = 0;
1584 options->num_user_hostfiles = 0;
1585 options->local_forwards = NULL;
1586 options->num_local_forwards = 0;
1587 options->remote_forwards = NULL;
1588 options->num_remote_forwards = 0;
1589 options->clear_forwardings = -1;
1590 options->log_level = SYSLOG_LEVEL_NOT_SET;
1591 options->preferred_authentications = NULL;
1592 options->bind_address = NULL;
1593 options->pkcs11_provider = NULL;
1594 options->enable_ssh_keysign = - 1;
1595 options->no_host_authentication_for_localhost = - 1;
1596 options->identities_only = - 1;
1597 options->rekey_limit = - 1;
1598 options->rekey_interval = -1;
1599 options->verify_host_key_dns = -1;
1600 options->server_alive_interval = -1;
1601 options->server_alive_count_max = -1;
1602 options->num_send_env = 0;
1603 options->control_path = NULL;
1604 options->control_master = -1;
1605 options->control_persist = -1;
1606 options->control_persist_timeout = 0;
1607 options->hash_known_hosts = -1;
1608 options->tun_open = -1;
1609 options->tun_local = -1;
1610 options->tun_remote = -1;
1611 options->local_command = NULL;
1612 options->permit_local_command = -1;
1613 options->use_roaming = -1;
1614 options->visual_host_key = -1;
1615 options->ip_qos_interactive = -1;
1616 options->ip_qos_bulk = -1;
1617 options->request_tty = -1;
1618 options->proxy_use_fdpass = -1;
1619 options->ignored_unknown = NULL;
1620 options->num_canonical_domains = 0;
1621 options->num_permitted_cnames = 0;
1622 options->canonicalize_max_dots = -1;
1623 options->canonicalize_fallback_local = -1;
1624 options->canonicalize_hostname = -1;
1625 options->version_addendum = NULL;
1626 options->hpn_disabled = -1;
1627 options->hpn_buffer_size = -1;
1628 options->tcp_rcv_buf_poll = -1;
1629 options->tcp_rcv_buf = -1;
1630 }
1631
1632 /*
1633 * A petite version of fill_default_options() that just fills the options
1634 * needed for hostname canonicalization to proceed.
1635 */
1636 void
fill_default_options_for_canonicalization(Options * options)1637 fill_default_options_for_canonicalization(Options *options)
1638 {
1639 if (options->canonicalize_max_dots == -1)
1640 options->canonicalize_max_dots = 1;
1641 if (options->canonicalize_fallback_local == -1)
1642 options->canonicalize_fallback_local = 1;
1643 if (options->canonicalize_hostname == -1)
1644 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1645 }
1646
1647 /*
1648 * Called after processing other sources of option data, this fills those
1649 * options for which no value has been specified with their default values.
1650 */
1651 void
fill_default_options(Options * options)1652 fill_default_options(Options * options)
1653 {
1654 if (options->forward_agent == -1)
1655 options->forward_agent = 0;
1656 if (options->forward_x11 == -1)
1657 options->forward_x11 = 0;
1658 if (options->forward_x11_trusted == -1)
1659 options->forward_x11_trusted = 0;
1660 if (options->forward_x11_timeout == -1)
1661 options->forward_x11_timeout = 1200;
1662 if (options->exit_on_forward_failure == -1)
1663 options->exit_on_forward_failure = 0;
1664 if (options->xauth_location == NULL)
1665 options->xauth_location = _PATH_XAUTH;
1666 if (options->gateway_ports == -1)
1667 options->gateway_ports = 0;
1668 if (options->use_privileged_port == -1)
1669 options->use_privileged_port = 0;
1670 if (options->rsa_authentication == -1)
1671 options->rsa_authentication = 1;
1672 if (options->pubkey_authentication == -1)
1673 options->pubkey_authentication = 1;
1674 if (options->challenge_response_authentication == -1)
1675 options->challenge_response_authentication = 1;
1676 if (options->gss_authentication == -1)
1677 options->gss_authentication = 0;
1678 if (options->gss_deleg_creds == -1)
1679 options->gss_deleg_creds = 0;
1680 if (options->password_authentication == -1)
1681 options->password_authentication = 1;
1682 if (options->kbd_interactive_authentication == -1)
1683 options->kbd_interactive_authentication = 1;
1684 if (options->rhosts_rsa_authentication == -1)
1685 options->rhosts_rsa_authentication = 0;
1686 if (options->hostbased_authentication == -1)
1687 options->hostbased_authentication = 0;
1688 if (options->batch_mode == -1)
1689 options->batch_mode = 0;
1690 if (options->check_host_ip == -1)
1691 options->check_host_ip = 0;
1692 if (options->strict_host_key_checking == -1)
1693 options->strict_host_key_checking = 2; /* 2 is default */
1694 if (options->compression == -1)
1695 options->compression = 0;
1696 if (options->tcp_keep_alive == -1)
1697 options->tcp_keep_alive = 1;
1698 if (options->compression_level == -1)
1699 options->compression_level = 6;
1700 if (options->port == -1)
1701 options->port = 0; /* Filled in ssh_connect. */
1702 if (options->address_family == -1)
1703 options->address_family = AF_UNSPEC;
1704 if (options->connection_attempts == -1)
1705 options->connection_attempts = 1;
1706 if (options->number_of_password_prompts == -1)
1707 options->number_of_password_prompts = 3;
1708 /* Selected in ssh_login(). */
1709 if (options->cipher == -1)
1710 options->cipher = SSH_CIPHER_NOT_SET;
1711 /* options->ciphers, default set in myproposals.h */
1712 /* options->macs, default set in myproposals.h */
1713 /* options->kex_algorithms, default set in myproposals.h */
1714 /* options->hostkeyalgorithms, default set in myproposals.h */
1715 if (options->protocol == SSH_PROTO_UNKNOWN)
1716 options->protocol = SSH_PROTO_2;
1717 if (options->num_identity_files == 0) {
1718 if (options->protocol & SSH_PROTO_1) {
1719 add_identity_file(options, "~/",
1720 _PATH_SSH_CLIENT_IDENTITY, 0);
1721 }
1722 if (options->protocol & SSH_PROTO_2) {
1723 add_identity_file(options, "~/",
1724 _PATH_SSH_CLIENT_ID_RSA, 0);
1725 add_identity_file(options, "~/",
1726 _PATH_SSH_CLIENT_ID_DSA, 0);
1727 #ifdef OPENSSL_HAS_ECC
1728 add_identity_file(options, "~/",
1729 _PATH_SSH_CLIENT_ID_ECDSA, 0);
1730 #endif
1731 add_identity_file(options, "~/",
1732 _PATH_SSH_CLIENT_ID_ED25519, 0);
1733 }
1734 }
1735 if (options->escape_char == -1)
1736 options->escape_char = '~';
1737 if (options->num_system_hostfiles == 0) {
1738 options->system_hostfiles[options->num_system_hostfiles++] =
1739 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1740 options->system_hostfiles[options->num_system_hostfiles++] =
1741 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1742 }
1743 if (options->num_user_hostfiles == 0) {
1744 options->user_hostfiles[options->num_user_hostfiles++] =
1745 xstrdup(_PATH_SSH_USER_HOSTFILE);
1746 options->user_hostfiles[options->num_user_hostfiles++] =
1747 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1748 }
1749 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1750 options->log_level = SYSLOG_LEVEL_INFO;
1751 if (options->clear_forwardings == 1)
1752 clear_forwardings(options);
1753 if (options->no_host_authentication_for_localhost == - 1)
1754 options->no_host_authentication_for_localhost = 0;
1755 if (options->identities_only == -1)
1756 options->identities_only = 0;
1757 if (options->enable_ssh_keysign == -1)
1758 options->enable_ssh_keysign = 0;
1759 if (options->rekey_limit == -1)
1760 options->rekey_limit = 0;
1761 if (options->rekey_interval == -1)
1762 options->rekey_interval = 0;
1763 #if HAVE_LDNS
1764 if (options->verify_host_key_dns == -1)
1765 /* automatically trust a verified SSHFP record */
1766 options->verify_host_key_dns = 1;
1767 #else
1768 if (options->verify_host_key_dns == -1)
1769 options->verify_host_key_dns = 0;
1770 #endif
1771 if (options->server_alive_interval == -1)
1772 options->server_alive_interval = 0;
1773 if (options->server_alive_count_max == -1)
1774 options->server_alive_count_max = 3;
1775 if (options->control_master == -1)
1776 options->control_master = 0;
1777 if (options->control_persist == -1) {
1778 options->control_persist = 0;
1779 options->control_persist_timeout = 0;
1780 }
1781 if (options->hash_known_hosts == -1)
1782 options->hash_known_hosts = 0;
1783 if (options->tun_open == -1)
1784 options->tun_open = SSH_TUNMODE_NO;
1785 if (options->tun_local == -1)
1786 options->tun_local = SSH_TUNID_ANY;
1787 if (options->tun_remote == -1)
1788 options->tun_remote = SSH_TUNID_ANY;
1789 if (options->permit_local_command == -1)
1790 options->permit_local_command = 0;
1791 if (options->use_roaming == -1)
1792 options->use_roaming = 1;
1793 if (options->visual_host_key == -1)
1794 options->visual_host_key = 0;
1795 if (options->ip_qos_interactive == -1)
1796 options->ip_qos_interactive = IPTOS_LOWDELAY;
1797 if (options->ip_qos_bulk == -1)
1798 options->ip_qos_bulk = IPTOS_THROUGHPUT;
1799 if (options->request_tty == -1)
1800 options->request_tty = REQUEST_TTY_AUTO;
1801 if (options->proxy_use_fdpass == -1)
1802 options->proxy_use_fdpass = 0;
1803 if (options->canonicalize_max_dots == -1)
1804 options->canonicalize_max_dots = 1;
1805 if (options->canonicalize_fallback_local == -1)
1806 options->canonicalize_fallback_local = 1;
1807 if (options->canonicalize_hostname == -1)
1808 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1809 #define CLEAR_ON_NONE(v) \
1810 do { \
1811 if (option_clear_or_none(v)) { \
1812 free(v); \
1813 v = NULL; \
1814 } \
1815 } while(0)
1816 CLEAR_ON_NONE(options->local_command);
1817 CLEAR_ON_NONE(options->proxy_command);
1818 CLEAR_ON_NONE(options->control_path);
1819 /* options->user will be set in the main program if appropriate */
1820 /* options->hostname will be set in the main program if appropriate */
1821 /* options->host_key_alias should not be set by default */
1822 /* options->preferred_authentications will be set in ssh */
1823 if (options->version_addendum == NULL)
1824 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
1825 if (options->hpn_disabled == -1)
1826 options->hpn_disabled = 0;
1827 if (options->hpn_buffer_size > -1)
1828 {
1829 u_int maxlen;
1830
1831 /* If a user tries to set the size to 0 set it to 1KB. */
1832 if (options->hpn_buffer_size == 0)
1833 options->hpn_buffer_size = 1024;
1834 /* Limit the buffer to BUFFER_MAX_LEN. */
1835 maxlen = buffer_get_max_len();
1836 if (options->hpn_buffer_size > (maxlen / 1024)) {
1837 debug("User requested buffer larger than %ub: %ub. "
1838 "Request reverted to %ub", maxlen,
1839 options->hpn_buffer_size * 1024, maxlen);
1840 options->hpn_buffer_size = maxlen;
1841 }
1842 debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1843 }
1844 if (options->tcp_rcv_buf == 0)
1845 options->tcp_rcv_buf = 1;
1846 if (options->tcp_rcv_buf > -1)
1847 options->tcp_rcv_buf *= 1024;
1848 if (options->tcp_rcv_buf_poll == -1)
1849 options->tcp_rcv_buf_poll = 1;
1850 }
1851
1852 /*
1853 * parse_forward
1854 * parses a string containing a port forwarding specification of the form:
1855 * dynamicfwd == 0
1856 * [listenhost:]listenport:connecthost:connectport
1857 * dynamicfwd == 1
1858 * [listenhost:]listenport
1859 * returns number of arguments parsed or zero on error
1860 */
1861 int
parse_forward(Forward * fwd,const char * fwdspec,int dynamicfwd,int remotefwd)1862 parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1863 {
1864 int i;
1865 char *p, *cp, *fwdarg[4];
1866
1867 memset(fwd, '\0', sizeof(*fwd));
1868
1869 cp = p = xstrdup(fwdspec);
1870
1871 /* skip leading spaces */
1872 while (isspace((u_char)*cp))
1873 cp++;
1874
1875 for (i = 0; i < 4; ++i)
1876 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1877 break;
1878
1879 /* Check for trailing garbage */
1880 if (cp != NULL)
1881 i = 0; /* failure */
1882
1883 switch (i) {
1884 case 1:
1885 fwd->listen_host = NULL;
1886 fwd->listen_port = a2port(fwdarg[0]);
1887 fwd->connect_host = xstrdup("socks");
1888 break;
1889
1890 case 2:
1891 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1892 fwd->listen_port = a2port(fwdarg[1]);
1893 fwd->connect_host = xstrdup("socks");
1894 break;
1895
1896 case 3:
1897 fwd->listen_host = NULL;
1898 fwd->listen_port = a2port(fwdarg[0]);
1899 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1900 fwd->connect_port = a2port(fwdarg[2]);
1901 break;
1902
1903 case 4:
1904 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1905 fwd->listen_port = a2port(fwdarg[1]);
1906 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1907 fwd->connect_port = a2port(fwdarg[3]);
1908 break;
1909 default:
1910 i = 0; /* failure */
1911 }
1912
1913 free(p);
1914
1915 if (dynamicfwd) {
1916 if (!(i == 1 || i == 2))
1917 goto fail_free;
1918 } else {
1919 if (!(i == 3 || i == 4))
1920 goto fail_free;
1921 if (fwd->connect_port <= 0)
1922 goto fail_free;
1923 }
1924
1925 if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1926 goto fail_free;
1927
1928 if (fwd->connect_host != NULL &&
1929 strlen(fwd->connect_host) >= NI_MAXHOST)
1930 goto fail_free;
1931 if (fwd->listen_host != NULL &&
1932 strlen(fwd->listen_host) >= NI_MAXHOST)
1933 goto fail_free;
1934
1935
1936 return (i);
1937
1938 fail_free:
1939 free(fwd->connect_host);
1940 fwd->connect_host = NULL;
1941 free(fwd->listen_host);
1942 fwd->listen_host = NULL;
1943 return (0);
1944 }
1945