readconf.c revision 1.16 1 /* $NetBSD: readconf.c,v 1.16 2015/08/13 10:33:21 christos Exp $ */
2 /* $OpenBSD: readconf.c,v 1.239 2015/07/30 00:01:34 djm Exp $ */
3 /*
4 * Author: Tatu Ylonen <ylo (at) cs.hut.fi>
5 * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
6 * All rights reserved
7 * Functions for reading the configuration files.
8 *
9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose. Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 */
15
16 #include "includes.h"
17 __RCSID("$NetBSD: readconf.c,v 1.16 2015/08/13 10:33:21 christos Exp $");
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/socket.h>
21 #include <sys/wait.h>
22 #include <sys/un.h>
23
24 #include <netinet/in.h>
25 #include <netinet/ip.h>
26
27 #include <ctype.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <netdb.h>
31 #include <paths.h>
32 #include <pwd.h>
33 #include <signal.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <limits.h>
38 #include <util.h>
39 #include <vis.h>
40
41 #include "xmalloc.h"
42 #include "ssh.h"
43 #include "compat.h"
44 #include "cipher.h"
45 #include "pathnames.h"
46 #include "log.h"
47 #include "sshkey.h"
48 #include "misc.h"
49 #include "readconf.h"
50 #include "match.h"
51 #include "kex.h"
52 #include "mac.h"
53 #include "fmt_scaled.h"
54 #include "uidswap.h"
55 #include "myproposal.h"
56 #include "digest.h"
57
58 /* Format of the configuration file:
59
60 # Configuration data is parsed as follows:
61 # 1. command line options
62 # 2. user-specific file
63 # 3. system-wide file
64 # Any configuration value is only changed the first time it is set.
65 # Thus, host-specific definitions should be at the beginning of the
66 # configuration file, and defaults at the end.
67
68 # Host-specific declarations. These may override anything above. A single
69 # host may match multiple declarations; these are processed in the order
70 # that they are given in.
71
72 Host *.ngs.fi ngs.fi
73 User foo
74
75 Host fake.com
76 HostName another.host.name.real.org
77 User blaah
78 Port 34289
79 ForwardX11 no
80 ForwardAgent no
81
82 Host books.com
83 RemoteForward 9999 shadows.cs.hut.fi:9999
84 Cipher 3des
85
86 Host fascist.blob.com
87 Port 23123
88 User tylonen
89 PasswordAuthentication no
90
91 Host puukko.hut.fi
92 User t35124p
93 ProxyCommand ssh-proxy %h %p
94
95 Host *.fr
96 PublicKeyAuthentication no
97
98 Host *.su
99 Cipher none
100 PasswordAuthentication no
101
102 Host vpn.fake.com
103 Tunnel yes
104 TunnelDevice 3
105
106 # Defaults for various options
107 Host *
108 ForwardAgent no
109 ForwardX11 no
110 PasswordAuthentication yes
111 RSAAuthentication yes
112 RhostsRSAAuthentication yes
113 StrictHostKeyChecking yes
114 TcpKeepAlive no
115 IdentityFile ~/.ssh/identity
116 Port 22
117 EscapeChar ~
118
119 */
120
121 /* Keyword tokens. */
122
123 typedef enum {
124 oBadOption,
125 oHost, oMatch,
126 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
127 oGatewayPorts, oExitOnForwardFailure,
128 oPasswordAuthentication, oRSAAuthentication,
129 oChallengeResponseAuthentication, oXAuthLocation,
130 #if defined(KRB4) || defined(KRB5)
131 oKerberosAuthentication,
132 #endif
133 #if defined(AFS) || defined(KRB5)
134 oKerberosTgtPassing,
135 #endif
136 #ifdef AFS
137 oAFSTokenPassing,
138 #endif
139 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
140 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
141 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
142 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
143 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
144 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
145 oPubkeyAuthentication,
146 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
147 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
148 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
149 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
150 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
151 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
152 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
153 oSendEnv, oControlPath, oControlMaster, oControlPersist,
154 oHashKnownHosts,
155 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
156 oVisualHostKey, oUseRoaming,
157 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
158 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
159 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
160 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
161 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
162 oPubkeyAcceptedKeyTypes,
163 oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
164 oHPNBufferSize,
165 oSendVersionFirst,
166 oIgnoredUnknownOption, oDeprecated, oUnsupported
167 } OpCodes;
168
169 /* Textual representations of the tokens. */
170
171 static struct {
172 const char *name;
173 OpCodes opcode;
174 } keywords[] = {
175 { "forwardagent", oForwardAgent },
176 { "forwardx11", oForwardX11 },
177 { "forwardx11trusted", oForwardX11Trusted },
178 { "forwardx11timeout", oForwardX11Timeout },
179 { "exitonforwardfailure", oExitOnForwardFailure },
180 { "xauthlocation", oXAuthLocation },
181 { "gatewayports", oGatewayPorts },
182 { "useprivilegedport", oUsePrivilegedPort },
183 { "rhostsauthentication", oDeprecated },
184 { "passwordauthentication", oPasswordAuthentication },
185 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
186 { "kbdinteractivedevices", oKbdInteractiveDevices },
187 { "rsaauthentication", oRSAAuthentication },
188 { "pubkeyauthentication", oPubkeyAuthentication },
189 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
190 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
191 { "hostbasedauthentication", oHostbasedAuthentication },
192 { "challengeresponseauthentication", oChallengeResponseAuthentication },
193 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
194 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
195 #if defined(KRB4) || defined(KRB5)
196 { "kerberosauthentication", oKerberosAuthentication },
197 #endif
198 #if defined(AFS) || defined(KRB5)
199 { "kerberostgtpassing", oKerberosTgtPassing },
200 { "kerberos5tgtpassing", oKerberosTgtPassing }, /* alias */
201 { "kerberos4tgtpassing", oKerberosTgtPassing }, /* alias */
202 #endif
203 #ifdef AFS
204 { "afstokenpassing", oAFSTokenPassing },
205 #endif
206 #if defined(GSSAPI)
207 { "gssapiauthentication", oGssAuthentication },
208 { "gssapidelegatecredentials", oGssDelegateCreds },
209 #else
210 { "gssapiauthentication", oUnsupported },
211 { "gssapidelegatecredentials", oUnsupported },
212 #endif
213 { "fallbacktorsh", oDeprecated },
214 { "usersh", oDeprecated },
215 { "identityfile", oIdentityFile },
216 { "identityfile2", oIdentityFile }, /* obsolete */
217 { "identitiesonly", oIdentitiesOnly },
218 { "hostname", oHostName },
219 { "hostkeyalias", oHostKeyAlias },
220 { "proxycommand", oProxyCommand },
221 { "port", oPort },
222 { "cipher", oCipher },
223 { "ciphers", oCiphers },
224 { "macs", oMacs },
225 { "protocol", oProtocol },
226 { "remoteforward", oRemoteForward },
227 { "localforward", oLocalForward },
228 { "user", oUser },
229 { "host", oHost },
230 { "match", oMatch },
231 { "escapechar", oEscapeChar },
232 { "globalknownhostsfile", oGlobalKnownHostsFile },
233 { "globalknownhostsfile2", oDeprecated },
234 { "userknownhostsfile", oUserKnownHostsFile },
235 { "userknownhostsfile2", oDeprecated },
236 { "connectionattempts", oConnectionAttempts },
237 { "batchmode", oBatchMode },
238 { "checkhostip", oCheckHostIP },
239 { "stricthostkeychecking", oStrictHostKeyChecking },
240 { "compression", oCompression },
241 { "compressionlevel", oCompressionLevel },
242 { "tcpkeepalive", oTCPKeepAlive },
243 { "keepalive", oTCPKeepAlive }, /* obsolete */
244 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
245 { "loglevel", oLogLevel },
246 { "dynamicforward", oDynamicForward },
247 { "preferredauthentications", oPreferredAuthentications },
248 { "hostkeyalgorithms", oHostKeyAlgorithms },
249 { "bindaddress", oBindAddress },
250 #ifdef ENABLE_PKCS11
251 { "smartcarddevice", oPKCS11Provider },
252 { "pkcs11provider", oPKCS11Provider },
253 #else
254 { "smartcarddevice", oUnsupported },
255 { "pkcs11provider", oUnsupported },
256 #endif
257 { "clearallforwardings", oClearAllForwardings },
258 { "enablesshkeysign", oEnableSSHKeysign },
259 { "verifyhostkeydns", oVerifyHostKeyDNS },
260 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
261 { "rekeylimit", oRekeyLimit },
262 { "connecttimeout", oConnectTimeout },
263 { "addressfamily", oAddressFamily },
264 { "serveraliveinterval", oServerAliveInterval },
265 { "serveralivecountmax", oServerAliveCountMax },
266 { "sendenv", oSendEnv },
267 { "controlpath", oControlPath },
268 { "controlmaster", oControlMaster },
269 { "controlpersist", oControlPersist },
270 { "hashknownhosts", oHashKnownHosts },
271 { "tunnel", oTunnel },
272 { "tunneldevice", oTunnelDevice },
273 { "localcommand", oLocalCommand },
274 { "permitlocalcommand", oPermitLocalCommand },
275 { "visualhostkey", oVisualHostKey },
276 { "useroaming", oUseRoaming },
277 { "kexalgorithms", oKexAlgorithms },
278 { "ipqos", oIPQoS },
279 { "requesttty", oRequestTTY },
280 { "proxyusefdpass", oProxyUseFdpass },
281 { "canonicaldomains", oCanonicalDomains },
282 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
283 { "canonicalizehostname", oCanonicalizeHostname },
284 { "canonicalizemaxdots", oCanonicalizeMaxDots },
285 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
286 { "streamlocalbindmask", oStreamLocalBindMask },
287 { "streamlocalbindunlink", oStreamLocalBindUnlink },
288 { "revokedhostkeys", oRevokedHostKeys },
289 { "fingerprinthash", oFingerprintHash },
290 { "updatehostkeys", oUpdateHostkeys },
291 { "hostbasedkeytypes", oHostbasedKeyTypes },
292 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
293 { "noneenabled", oNoneEnabled },
294 { "tcprcvbufpoll", oTcpRcvBufPoll },
295 { "tcprcvbuf", oTcpRcvBuf },
296 { "noneswitch", oNoneSwitch },
297 { "hpndisabled", oHPNDisabled },
298 { "hpnbuffersize", oHPNBufferSize },
299 { "sendversionfirst", oSendVersionFirst },
300 { "ignoreunknown", oIgnoreUnknown },
301 { NULL, oBadOption }
302 };
303
304 /*
305 * Adds a local TCP/IP port forward to options. Never returns if there is an
306 * error.
307 */
308
309 void
310 add_local_forward(Options *options, const struct Forward *newfwd)
311 {
312 struct Forward *fwd;
313 extern uid_t original_real_uid;
314
315 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 &&
316 newfwd->listen_path == NULL)
317 fatal("Privileged ports can only be forwarded by root.");
318 options->local_forwards = xreallocarray(options->local_forwards,
319 options->num_local_forwards + 1,
320 sizeof(*options->local_forwards));
321 fwd = &options->local_forwards[options->num_local_forwards++];
322
323 fwd->listen_host = newfwd->listen_host;
324 fwd->listen_port = newfwd->listen_port;
325 fwd->listen_path = newfwd->listen_path;
326 fwd->connect_host = newfwd->connect_host;
327 fwd->connect_port = newfwd->connect_port;
328 fwd->connect_path = newfwd->connect_path;
329 }
330
331 /*
332 * Adds a remote TCP/IP port forward to options. Never returns if there is
333 * an error.
334 */
335
336 void
337 add_remote_forward(Options *options, const struct Forward *newfwd)
338 {
339 struct Forward *fwd;
340
341 options->remote_forwards = xreallocarray(options->remote_forwards,
342 options->num_remote_forwards + 1,
343 sizeof(*options->remote_forwards));
344 fwd = &options->remote_forwards[options->num_remote_forwards++];
345
346 fwd->listen_host = newfwd->listen_host;
347 fwd->listen_port = newfwd->listen_port;
348 fwd->listen_path = newfwd->listen_path;
349 fwd->connect_host = newfwd->connect_host;
350 fwd->connect_port = newfwd->connect_port;
351 fwd->connect_path = newfwd->connect_path;
352 fwd->handle = newfwd->handle;
353 fwd->allocated_port = 0;
354 }
355
356 static void
357 clear_forwardings(Options *options)
358 {
359 int i;
360
361 for (i = 0; i < options->num_local_forwards; i++) {
362 free(options->local_forwards[i].listen_host);
363 free(options->local_forwards[i].listen_path);
364 free(options->local_forwards[i].connect_host);
365 free(options->local_forwards[i].connect_path);
366 }
367 if (options->num_local_forwards > 0) {
368 free(options->local_forwards);
369 options->local_forwards = NULL;
370 }
371 options->num_local_forwards = 0;
372 for (i = 0; i < options->num_remote_forwards; i++) {
373 free(options->remote_forwards[i].listen_host);
374 free(options->remote_forwards[i].listen_path);
375 free(options->remote_forwards[i].connect_host);
376 free(options->remote_forwards[i].connect_path);
377 }
378 if (options->num_remote_forwards > 0) {
379 free(options->remote_forwards);
380 options->remote_forwards = NULL;
381 }
382 options->num_remote_forwards = 0;
383 options->tun_open = SSH_TUNMODE_NO;
384 }
385
386 void
387 add_identity_file(Options *options, const char *dir, const char *filename,
388 int userprovided)
389 {
390 char *path;
391 int i;
392
393 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
394 fatal("Too many identity files specified (max %d)",
395 SSH_MAX_IDENTITY_FILES);
396
397 if (dir == NULL) /* no dir, filename is absolute */
398 path = xstrdup(filename);
399 else
400 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
401
402 /* Avoid registering duplicates */
403 for (i = 0; i < options->num_identity_files; i++) {
404 if (options->identity_file_userprovided[i] == userprovided &&
405 strcmp(options->identity_files[i], path) == 0) {
406 debug2("%s: ignoring duplicate key %s", __func__, path);
407 free(path);
408 return;
409 }
410 }
411
412 options->identity_file_userprovided[options->num_identity_files] =
413 userprovided;
414 options->identity_files[options->num_identity_files++] = path;
415 }
416
417 int
418 default_ssh_port(void)
419 {
420 static int port;
421 struct servent *sp;
422
423 if (port == 0) {
424 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
425 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
426 }
427 return port;
428 }
429
430 /*
431 * Execute a command in a shell.
432 * Return its exit status or -1 on abnormal exit.
433 */
434 static int
435 execute_in_shell(const char *cmd)
436 {
437 const char *shell;
438 char *command_string;
439 pid_t pid;
440 int devnull, status;
441 extern uid_t original_real_uid;
442
443 if ((shell = getenv("SHELL")) == NULL)
444 shell = _PATH_BSHELL;
445
446 /*
447 * Use "exec" to avoid "sh -c" processes on some platforms
448 * (e.g. Solaris)
449 */
450 xasprintf(&command_string, "exec %s", cmd);
451
452 /* Need this to redirect subprocess stdin/out */
453 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
454 fatal("open(/dev/null): %s", strerror(errno));
455
456 debug("Executing command: '%.500s'", cmd);
457
458 /* Fork and execute the command. */
459 if ((pid = fork()) == 0) {
460 char *argv[4];
461
462 /* Child. Permanently give up superuser privileges. */
463 permanently_drop_suid(original_real_uid);
464
465 /* Redirect child stdin and stdout. Leave stderr */
466 if (dup2(devnull, STDIN_FILENO) == -1)
467 fatal("dup2: %s", strerror(errno));
468 if (dup2(devnull, STDOUT_FILENO) == -1)
469 fatal("dup2: %s", strerror(errno));
470 if (devnull > STDERR_FILENO)
471 close(devnull);
472 if (closefrom(STDERR_FILENO + 1) == -1)
473 fatal("closefrom: %s", strerror(errno));
474
475 argv[0] = __UNCONST(shell);
476 argv[1] = __UNCONST("-c");
477 argv[2] = command_string;
478 argv[3] = NULL;
479
480 execv(argv[0], argv);
481 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
482 /* Die with signal to make this error apparent to parent. */
483 signal(SIGTERM, SIG_DFL);
484 kill(getpid(), SIGTERM);
485 _exit(1);
486 }
487 /* Parent. */
488 if (pid < 0)
489 fatal("%s: fork: %.100s", __func__, strerror(errno));
490
491 close(devnull);
492 free(command_string);
493
494 while (waitpid(pid, &status, 0) == -1) {
495 if (errno != EINTR && errno != EAGAIN)
496 fatal("%s: waitpid: %s", __func__, strerror(errno));
497 }
498 if (!WIFEXITED(status)) {
499 error("command '%.100s' exited abnormally", cmd);
500 return -1;
501 }
502 debug3("command returned status %d", WEXITSTATUS(status));
503 return WEXITSTATUS(status);
504 }
505
506 /*
507 * Parse and execute a Match directive.
508 */
509 static int
510 match_cfg_line(Options *options, char **condition, struct passwd *pw,
511 const char *host_arg, const char *original_host, int post_canon,
512 const char *filename, int linenum)
513 {
514 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
515 const char *ruser;
516 int r, port, this_result, result = 1, attributes = 0, negate;
517 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
518
519 /*
520 * Configuration is likely to be incomplete at this point so we
521 * must be prepared to use default values.
522 */
523 port = options->port <= 0 ? default_ssh_port() : options->port;
524 ruser = options->user == NULL ? pw->pw_name : options->user;
525 if (options->hostname != NULL) {
526 /* NB. Please keep in sync with ssh.c:main() */
527 host = percent_expand(options->hostname,
528 "h", host_arg, (char *)NULL);
529 } else
530 host = xstrdup(host_arg);
531
532 debug2("checking match for '%s' host %s originally %s",
533 cp, host, original_host);
534 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
535 criteria = NULL;
536 this_result = 1;
537 if ((negate = attrib[0] == '!'))
538 attrib++;
539 /* criteria "all" and "canonical" have no argument */
540 if (strcasecmp(attrib, "all") == 0) {
541 if (attributes > 1 ||
542 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
543 error("%.200s line %d: '%s' cannot be combined "
544 "with other Match attributes",
545 filename, linenum, oattrib);
546 result = -1;
547 goto out;
548 }
549 if (result)
550 result = negate ? 0 : 1;
551 goto out;
552 }
553 attributes++;
554 if (strcasecmp(attrib, "canonical") == 0) {
555 r = !!post_canon; /* force bitmask member to boolean */
556 if (r == (negate ? 1 : 0))
557 this_result = result = 0;
558 debug3("%.200s line %d: %smatched '%s'",
559 filename, linenum,
560 this_result ? "" : "not ", oattrib);
561 continue;
562 }
563 /* All other criteria require an argument */
564 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
565 error("Missing Match criteria for %s", attrib);
566 result = -1;
567 goto out;
568 }
569 if (strcasecmp(attrib, "host") == 0) {
570 criteria = xstrdup(host);
571 r = match_hostname(host, arg) == 1;
572 if (r == (negate ? 1 : 0))
573 this_result = result = 0;
574 } else if (strcasecmp(attrib, "originalhost") == 0) {
575 criteria = xstrdup(original_host);
576 r = match_hostname(original_host, arg) == 1;
577 if (r == (negate ? 1 : 0))
578 this_result = result = 0;
579 } else if (strcasecmp(attrib, "user") == 0) {
580 criteria = xstrdup(ruser);
581 r = match_pattern_list(ruser, arg, 0) == 1;
582 if (r == (negate ? 1 : 0))
583 this_result = result = 0;
584 } else if (strcasecmp(attrib, "localuser") == 0) {
585 criteria = xstrdup(pw->pw_name);
586 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
587 if (r == (negate ? 1 : 0))
588 this_result = result = 0;
589 } else if (strcasecmp(attrib, "exec") == 0) {
590 if (gethostname(thishost, sizeof(thishost)) == -1)
591 fatal("gethostname: %s", strerror(errno));
592 strlcpy(shorthost, thishost, sizeof(shorthost));
593 shorthost[strcspn(thishost, ".")] = '\0';
594 snprintf(portstr, sizeof(portstr), "%d", port);
595
596 cmd = percent_expand(arg,
597 "L", shorthost,
598 "d", pw->pw_dir,
599 "h", host,
600 "l", thishost,
601 "n", original_host,
602 "p", portstr,
603 "r", ruser,
604 "u", pw->pw_name,
605 (char *)NULL);
606 if (result != 1) {
607 /* skip execution if prior predicate failed */
608 debug3("%.200s line %d: skipped exec "
609 "\"%.100s\"", filename, linenum, cmd);
610 free(cmd);
611 continue;
612 }
613 r = execute_in_shell(cmd);
614 if (r == -1) {
615 fatal("%.200s line %d: match exec "
616 "'%.100s' error", filename,
617 linenum, cmd);
618 }
619 criteria = xstrdup(cmd);
620 free(cmd);
621 /* Force exit status to boolean */
622 r = r == 0;
623 if (r == (negate ? 1 : 0))
624 this_result = result = 0;
625 } else {
626 error("Unsupported Match attribute %s", attrib);
627 result = -1;
628 goto out;
629 }
630 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
631 filename, linenum, this_result ? "": "not ",
632 oattrib, criteria);
633 free(criteria);
634 }
635 if (attributes == 0) {
636 error("One or more attributes required for Match");
637 result = -1;
638 goto out;
639 }
640 out:
641 if (result != -1)
642 debug2("match %sfound", result ? "" : "not ");
643 *condition = cp;
644 free(host);
645 return result;
646 }
647
648 /* Check and prepare a domain name: removes trailing '.' and lowercases */
649 static void
650 valid_domain(char *name, const char *filename, int linenum)
651 {
652 size_t i, l = strlen(name);
653 u_char c, last = '\0';
654
655 if (l == 0)
656 fatal("%s line %d: empty hostname suffix", filename, linenum);
657 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
658 fatal("%s line %d: hostname suffix \"%.100s\" "
659 "starts with invalid character", filename, linenum, name);
660 for (i = 0; i < l; i++) {
661 c = tolower((u_char)name[i]);
662 name[i] = (char)c;
663 if (last == '.' && c == '.')
664 fatal("%s line %d: hostname suffix \"%.100s\" contains "
665 "consecutive separators", filename, linenum, name);
666 if (c != '.' && c != '-' && !isalnum(c) &&
667 c != '_') /* technically invalid, but common */
668 fatal("%s line %d: hostname suffix \"%.100s\" contains "
669 "invalid characters", filename, linenum, name);
670 last = c;
671 }
672 if (name[l - 1] == '.')
673 name[l - 1] = '\0';
674 }
675
676 /*
677 * Returns the number of the token pointed to by cp or oBadOption.
678 */
679 static OpCodes
680 parse_token(const char *cp, const char *filename, int linenum,
681 const char *ignored_unknown)
682 {
683 int i;
684
685 for (i = 0; keywords[i].name; i++)
686 if (strcmp(cp, keywords[i].name) == 0)
687 return keywords[i].opcode;
688 if (ignored_unknown != NULL &&
689 match_pattern_list(cp, ignored_unknown, 1) == 1)
690 return oIgnoredUnknownOption;
691 error("%s: line %d: Bad configuration option: %s",
692 filename, linenum, cp);
693 return oBadOption;
694 }
695
696 /* Multistate option parsing */
697 struct multistate {
698 const char *key;
699 int value;
700 };
701 static const struct multistate multistate_flag[] = {
702 { "true", 1 },
703 { "false", 0 },
704 { "yes", 1 },
705 { "no", 0 },
706 { NULL, -1 }
707 };
708 static const struct multistate multistate_yesnoask[] = {
709 { "true", 1 },
710 { "false", 0 },
711 { "yes", 1 },
712 { "no", 0 },
713 { "ask", 2 },
714 { NULL, -1 }
715 };
716 static const struct multistate multistate_addressfamily[] = {
717 { "inet", AF_INET },
718 { "inet6", AF_INET6 },
719 { "any", AF_UNSPEC },
720 { NULL, -1 }
721 };
722 static const struct multistate multistate_controlmaster[] = {
723 { "true", SSHCTL_MASTER_YES },
724 { "yes", SSHCTL_MASTER_YES },
725 { "false", SSHCTL_MASTER_NO },
726 { "no", SSHCTL_MASTER_NO },
727 { "auto", SSHCTL_MASTER_AUTO },
728 { "ask", SSHCTL_MASTER_ASK },
729 { "autoask", SSHCTL_MASTER_AUTO_ASK },
730 { NULL, -1 }
731 };
732 static const struct multistate multistate_tunnel[] = {
733 { "ethernet", SSH_TUNMODE_ETHERNET },
734 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
735 { "true", SSH_TUNMODE_DEFAULT },
736 { "yes", SSH_TUNMODE_DEFAULT },
737 { "false", SSH_TUNMODE_NO },
738 { "no", SSH_TUNMODE_NO },
739 { NULL, -1 }
740 };
741 static const struct multistate multistate_requesttty[] = {
742 { "true", REQUEST_TTY_YES },
743 { "yes", REQUEST_TTY_YES },
744 { "false", REQUEST_TTY_NO },
745 { "no", REQUEST_TTY_NO },
746 { "force", REQUEST_TTY_FORCE },
747 { "auto", REQUEST_TTY_AUTO },
748 { NULL, -1 }
749 };
750 static const struct multistate multistate_canonicalizehostname[] = {
751 { "true", SSH_CANONICALISE_YES },
752 { "false", SSH_CANONICALISE_NO },
753 { "yes", SSH_CANONICALISE_YES },
754 { "no", SSH_CANONICALISE_NO },
755 { "always", SSH_CANONICALISE_ALWAYS },
756 { NULL, -1 }
757 };
758
759 /*
760 * Processes a single option line as used in the configuration files. This
761 * only sets those values that have not already been set.
762 */
763 #define WHITESPACE " \t\r\n"
764 int
765 process_config_line(Options *options, struct passwd *pw, const char *host,
766 const char *original_host, char *line, const char *filename,
767 int linenum, int *activep, int flags)
768 {
769 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
770 char **cpptr, fwdarg[256];
771 u_int i, *uintptr, max_entries = 0;
772 int negated, opcode, *intptr, value, value2, cmdline = 0;
773 LogLevel *log_level_ptr;
774 long long val64;
775 size_t len;
776 struct Forward fwd;
777 const struct multistate *multistate_ptr;
778 struct allowed_cname *cname;
779
780 if (activep == NULL) { /* We are processing a command line directive */
781 cmdline = 1;
782 activep = &cmdline;
783 }
784
785 /* Strip trailing whitespace */
786 if ((len = strlen(line)) == 0)
787 return 0;
788 for (len--; len > 0; len--) {
789 if (strchr(WHITESPACE, line[len]) == NULL)
790 break;
791 line[len] = '\0';
792 }
793
794 s = line;
795 /* Get the keyword. (Each line is supposed to begin with a keyword). */
796 if ((keyword = strdelim(&s)) == NULL)
797 return 0;
798 /* Ignore leading whitespace. */
799 if (*keyword == '\0')
800 keyword = strdelim(&s);
801 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
802 return 0;
803 /* Match lowercase keyword */
804 lowercase(keyword);
805
806 opcode = parse_token(keyword, filename, linenum,
807 options->ignored_unknown);
808
809 switch (opcode) {
810 case oBadOption:
811 /* don't panic, but count bad options */
812 return -1;
813 /* NOTREACHED */
814 case oIgnoredUnknownOption:
815 debug("%s line %d: Ignored unknown option \"%s\"",
816 filename, linenum, keyword);
817 return 0;
818 case oConnectTimeout:
819 intptr = &options->connection_timeout;
820 parse_time:
821 arg = strdelim(&s);
822 if (!arg || *arg == '\0')
823 fatal("%s line %d: missing time value.",
824 filename, linenum);
825 if (strcmp(arg, "none") == 0)
826 value = -1;
827 else if ((value = convtime(arg)) == -1)
828 fatal("%s line %d: invalid time value.",
829 filename, linenum);
830 if (*activep && *intptr == -1)
831 *intptr = value;
832 break;
833
834 case oForwardAgent:
835 intptr = &options->forward_agent;
836 parse_flag:
837 multistate_ptr = multistate_flag;
838 parse_multistate:
839 arg = strdelim(&s);
840 if (!arg || *arg == '\0')
841 fatal("%s line %d: missing argument.",
842 filename, linenum);
843 value = -1;
844 for (i = 0; multistate_ptr[i].key != NULL; i++) {
845 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
846 value = multistate_ptr[i].value;
847 break;
848 }
849 }
850 if (value == -1)
851 fatal("%s line %d: unsupported option \"%s\".",
852 filename, linenum, arg);
853 if (*activep && *intptr == -1)
854 *intptr = value;
855 break;
856
857 case oForwardX11:
858 intptr = &options->forward_x11;
859 goto parse_flag;
860
861 case oForwardX11Trusted:
862 intptr = &options->forward_x11_trusted;
863 goto parse_flag;
864
865 case oForwardX11Timeout:
866 intptr = &options->forward_x11_timeout;
867 goto parse_time;
868
869 case oGatewayPorts:
870 intptr = &options->fwd_opts.gateway_ports;
871 goto parse_flag;
872
873 case oExitOnForwardFailure:
874 intptr = &options->exit_on_forward_failure;
875 goto parse_flag;
876
877 case oUsePrivilegedPort:
878 intptr = &options->use_privileged_port;
879 goto parse_flag;
880
881 case oPasswordAuthentication:
882 intptr = &options->password_authentication;
883 goto parse_flag;
884
885 case oKbdInteractiveAuthentication:
886 intptr = &options->kbd_interactive_authentication;
887 goto parse_flag;
888
889 case oKbdInteractiveDevices:
890 charptr = &options->kbd_interactive_devices;
891 goto parse_string;
892
893 case oPubkeyAuthentication:
894 intptr = &options->pubkey_authentication;
895 goto parse_flag;
896
897 case oRSAAuthentication:
898 intptr = &options->rsa_authentication;
899 goto parse_flag;
900
901 case oRhostsRSAAuthentication:
902 intptr = &options->rhosts_rsa_authentication;
903 goto parse_flag;
904
905 case oHostbasedAuthentication:
906 intptr = &options->hostbased_authentication;
907 goto parse_flag;
908
909 case oChallengeResponseAuthentication:
910 intptr = &options->challenge_response_authentication;
911 goto parse_flag;
912
913 #if defined(KRB4) || defined(KRB5)
914 case oKerberosAuthentication:
915 intptr = &options->kerberos_authentication;
916 goto parse_flag;
917 #endif
918 #if defined(AFS) || defined(KRB5)
919 case oKerberosTgtPassing:
920 intptr = &options->kerberos_tgt_passing;
921 goto parse_flag;
922 #endif
923
924 case oGssAuthentication:
925 intptr = &options->gss_authentication;
926 goto parse_flag;
927
928 #ifdef AFS
929 case oAFSTokenPassing:
930 intptr = &options->afs_token_passing;
931 goto parse_flag;
932 #endif
933
934 case oGssDelegateCreds:
935 intptr = &options->gss_deleg_creds;
936 goto parse_flag;
937
938 case oBatchMode:
939 intptr = &options->batch_mode;
940 goto parse_flag;
941
942 case oCheckHostIP:
943 intptr = &options->check_host_ip;
944 goto parse_flag;
945
946 case oNoneEnabled:
947 intptr = &options->none_enabled;
948 goto parse_flag;
949
950 /* we check to see if the command comes from the */
951 /* command line or not. If it does then enable it */
952 /* otherwise fail. NONE should never be a default configuration */
953 case oNoneSwitch:
954 if(strcmp(filename,"command-line")==0)
955 {
956 intptr = &options->none_switch;
957 goto parse_flag;
958 } else {
959 error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
960 error("Continuing...");
961 debug("NoneSwitch directive found in %.200s.", filename);
962 return 0;
963 }
964
965 case oHPNDisabled:
966 intptr = &options->hpn_disabled;
967 goto parse_flag;
968
969 case oHPNBufferSize:
970 intptr = &options->hpn_buffer_size;
971 goto parse_int;
972
973 case oTcpRcvBufPoll:
974 intptr = &options->tcp_rcv_buf_poll;
975 goto parse_flag;
976
977 case oVerifyHostKeyDNS:
978 intptr = &options->verify_host_key_dns;
979 multistate_ptr = multistate_yesnoask;
980 goto parse_multistate;
981
982 case oStrictHostKeyChecking:
983 intptr = &options->strict_host_key_checking;
984 multistate_ptr = multistate_yesnoask;
985 goto parse_multistate;
986
987 case oCompression:
988 intptr = &options->compression;
989 goto parse_flag;
990
991 case oTCPKeepAlive:
992 intptr = &options->tcp_keep_alive;
993 goto parse_flag;
994
995 case oNoHostAuthenticationForLocalhost:
996 intptr = &options->no_host_authentication_for_localhost;
997 goto parse_flag;
998
999 case oNumberOfPasswordPrompts:
1000 intptr = &options->number_of_password_prompts;
1001 goto parse_int;
1002
1003 case oCompressionLevel:
1004 intptr = &options->compression_level;
1005 goto parse_int;
1006
1007 case oRekeyLimit:
1008 arg = strdelim(&s);
1009 if (!arg || *arg == '\0')
1010 fatal("%.200s line %d: Missing argument.", filename,
1011 linenum);
1012 if (strcmp(arg, "default") == 0) {
1013 val64 = 0;
1014 } else {
1015 if (scan_scaled(arg, &val64) == -1)
1016 fatal("%.200s line %d: Bad number '%s': %s",
1017 filename, linenum, arg, strerror(errno));
1018 /* check for too-large or too-small limits */
1019 if (val64 > UINT_MAX)
1020 fatal("%.200s line %d: RekeyLimit too large",
1021 filename, linenum);
1022 if (val64 != 0 && val64 < 16)
1023 fatal("%.200s line %d: RekeyLimit too small",
1024 filename, linenum);
1025 }
1026 if (*activep && options->rekey_limit == -1)
1027 options->rekey_limit = (u_int32_t)val64;
1028 if (s != NULL) { /* optional rekey interval present */
1029 if (strcmp(s, "none") == 0) {
1030 (void)strdelim(&s); /* discard */
1031 break;
1032 }
1033 intptr = &options->rekey_interval;
1034 goto parse_time;
1035 }
1036 break;
1037
1038 case oIdentityFile:
1039 arg = strdelim(&s);
1040 if (!arg || *arg == '\0')
1041 fatal("%.200s line %d: Missing argument.", filename, linenum);
1042 if (*activep) {
1043 intptr = &options->num_identity_files;
1044 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1045 fatal("%.200s line %d: Too many identity files specified (max %d).",
1046 filename, linenum, SSH_MAX_IDENTITY_FILES);
1047 add_identity_file(options, NULL,
1048 arg, flags & SSHCONF_USERCONF);
1049 }
1050 break;
1051
1052 case oXAuthLocation:
1053 charptr=&options->xauth_location;
1054 goto parse_string;
1055
1056 case oUser:
1057 charptr = &options->user;
1058 parse_string:
1059 arg = strdelim(&s);
1060 if (!arg || *arg == '\0')
1061 fatal("%.200s line %d: Missing argument.",
1062 filename, linenum);
1063 if (*activep && *charptr == NULL)
1064 *charptr = xstrdup(arg);
1065 break;
1066
1067 case oGlobalKnownHostsFile:
1068 cpptr = (char **)&options->system_hostfiles;
1069 uintptr = &options->num_system_hostfiles;
1070 max_entries = SSH_MAX_HOSTS_FILES;
1071 parse_char_array:
1072 if (*activep && *uintptr == 0) {
1073 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1074 if ((*uintptr) >= max_entries)
1075 fatal("%s line %d: "
1076 "too many authorized keys files.",
1077 filename, linenum);
1078 cpptr[(*uintptr)++] = xstrdup(arg);
1079 }
1080 }
1081 return 0;
1082
1083 case oUserKnownHostsFile:
1084 cpptr = (char **)&options->user_hostfiles;
1085 uintptr = &options->num_user_hostfiles;
1086 max_entries = SSH_MAX_HOSTS_FILES;
1087 goto parse_char_array;
1088
1089 case oHostName:
1090 charptr = &options->hostname;
1091 goto parse_string;
1092
1093 case oHostKeyAlias:
1094 charptr = &options->host_key_alias;
1095 goto parse_string;
1096
1097 case oPreferredAuthentications:
1098 charptr = &options->preferred_authentications;
1099 goto parse_string;
1100
1101 case oBindAddress:
1102 charptr = &options->bind_address;
1103 goto parse_string;
1104
1105 case oPKCS11Provider:
1106 charptr = &options->pkcs11_provider;
1107 goto parse_string;
1108
1109 case oProxyCommand:
1110 charptr = &options->proxy_command;
1111 parse_command:
1112 if (s == NULL)
1113 fatal("%.200s line %d: Missing argument.", filename, linenum);
1114 len = strspn(s, WHITESPACE "=");
1115 if (*activep && *charptr == NULL)
1116 *charptr = xstrdup(s + len);
1117 return 0;
1118
1119 case oPort:
1120 intptr = &options->port;
1121 parse_int:
1122 arg = strdelim(&s);
1123 if (!arg || *arg == '\0')
1124 fatal("%.200s line %d: Missing argument.", filename, linenum);
1125 if (arg[0] < '0' || arg[0] > '9')
1126 fatal("%.200s line %d: Bad number.", filename, linenum);
1127
1128 /* Octal, decimal, or hex format? */
1129 value = strtol(arg, &endofnumber, 0);
1130 if (arg == endofnumber)
1131 fatal("%.200s line %d: Bad number.", filename, linenum);
1132 if (*activep && *intptr == -1)
1133 *intptr = value;
1134 break;
1135
1136 case oConnectionAttempts:
1137 intptr = &options->connection_attempts;
1138 goto parse_int;
1139
1140 case oTcpRcvBuf:
1141 intptr = &options->tcp_rcv_buf;
1142 goto parse_int;
1143
1144 case oCipher:
1145 intptr = &options->cipher;
1146 arg = strdelim(&s);
1147 if (!arg || *arg == '\0')
1148 fatal("%.200s line %d: Missing argument.", filename, linenum);
1149 value = cipher_number(arg);
1150 if (value == -1)
1151 fatal("%.200s line %d: Bad cipher '%s'.",
1152 filename, linenum, arg ? arg : "<NONE>");
1153 if (*activep && *intptr == -1)
1154 *intptr = value;
1155 break;
1156
1157 case oCiphers:
1158 arg = strdelim(&s);
1159 if (!arg || *arg == '\0')
1160 fatal("%.200s line %d: Missing argument.", filename, linenum);
1161 if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1162 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1163 filename, linenum, arg ? arg : "<NONE>");
1164 if (*activep && options->ciphers == NULL)
1165 options->ciphers = xstrdup(arg);
1166 break;
1167
1168 case oMacs:
1169 arg = strdelim(&s);
1170 if (!arg || *arg == '\0')
1171 fatal("%.200s line %d: Missing argument.", filename, linenum);
1172 if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1173 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1174 filename, linenum, arg ? arg : "<NONE>");
1175 if (*activep && options->macs == NULL)
1176 options->macs = xstrdup(arg);
1177 break;
1178
1179 case oKexAlgorithms:
1180 arg = strdelim(&s);
1181 if (!arg || *arg == '\0')
1182 fatal("%.200s line %d: Missing argument.",
1183 filename, linenum);
1184 if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1185 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1186 filename, linenum, arg ? arg : "<NONE>");
1187 if (*activep && options->kex_algorithms == NULL)
1188 options->kex_algorithms = xstrdup(arg);
1189 break;
1190
1191 case oHostKeyAlgorithms:
1192 charptr = &options->hostkeyalgorithms;
1193 parse_keytypes:
1194 arg = strdelim(&s);
1195 if (!arg || *arg == '\0')
1196 fatal("%.200s line %d: Missing argument.",
1197 filename, linenum);
1198 if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1199 fatal("%s line %d: Bad key types '%s'.",
1200 filename, linenum, arg ? arg : "<NONE>");
1201 if (*activep && *charptr == NULL)
1202 *charptr = xstrdup(arg);
1203 break;
1204
1205 case oProtocol:
1206 intptr = &options->protocol;
1207 arg = strdelim(&s);
1208 if (!arg || *arg == '\0')
1209 fatal("%.200s line %d: Missing argument.", filename, linenum);
1210 value = proto_spec(arg);
1211 if (value == SSH_PROTO_UNKNOWN)
1212 fatal("%.200s line %d: Bad protocol spec '%s'.",
1213 filename, linenum, arg ? arg : "<NONE>");
1214 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1215 *intptr = value;
1216 break;
1217
1218 case oLogLevel:
1219 log_level_ptr = &options->log_level;
1220 arg = strdelim(&s);
1221 value = log_level_number(arg);
1222 if (value == SYSLOG_LEVEL_NOT_SET)
1223 fatal("%.200s line %d: unsupported log level '%s'",
1224 filename, linenum, arg ? arg : "<NONE>");
1225 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1226 *log_level_ptr = (LogLevel) value;
1227 break;
1228
1229 case oLocalForward:
1230 case oRemoteForward:
1231 case oDynamicForward:
1232 arg = strdelim(&s);
1233 if (arg == NULL || *arg == '\0')
1234 fatal("%.200s line %d: Missing port argument.",
1235 filename, linenum);
1236
1237 if (opcode == oLocalForward ||
1238 opcode == oRemoteForward) {
1239 arg2 = strdelim(&s);
1240 if (arg2 == NULL || *arg2 == '\0')
1241 fatal("%.200s line %d: Missing target argument.",
1242 filename, linenum);
1243
1244 /* construct a string for parse_forward */
1245 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1246 } else if (opcode == oDynamicForward) {
1247 strlcpy(fwdarg, arg, sizeof(fwdarg));
1248 }
1249
1250 if (parse_forward(&fwd, fwdarg,
1251 opcode == oDynamicForward ? 1 : 0,
1252 opcode == oRemoteForward ? 1 : 0) == 0)
1253 fatal("%.200s line %d: Bad forwarding specification.",
1254 filename, linenum);
1255
1256 if (*activep) {
1257 if (opcode == oLocalForward ||
1258 opcode == oDynamicForward)
1259 add_local_forward(options, &fwd);
1260 else if (opcode == oRemoteForward)
1261 add_remote_forward(options, &fwd);
1262 }
1263 break;
1264
1265 case oClearAllForwardings:
1266 intptr = &options->clear_forwardings;
1267 goto parse_flag;
1268
1269 case oHost:
1270 if (cmdline)
1271 fatal("Host directive not supported as a command-line "
1272 "option");
1273 *activep = 0;
1274 arg2 = NULL;
1275 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1276 negated = *arg == '!';
1277 if (negated)
1278 arg++;
1279 if (match_pattern(host, arg)) {
1280 if (negated) {
1281 debug("%.200s line %d: Skipping Host "
1282 "block because of negated match "
1283 "for %.100s", filename, linenum,
1284 arg);
1285 *activep = 0;
1286 break;
1287 }
1288 if (!*activep)
1289 arg2 = arg; /* logged below */
1290 *activep = 1;
1291 }
1292 }
1293 if (*activep)
1294 debug("%.200s line %d: Applying options for %.100s",
1295 filename, linenum, arg2);
1296 /* Avoid garbage check below, as strdelim is done. */
1297 return 0;
1298
1299 case oMatch:
1300 if (cmdline)
1301 fatal("Host directive not supported as a command-line "
1302 "option");
1303 value = match_cfg_line(options, &s, pw, host, original_host,
1304 flags & SSHCONF_POSTCANON, filename, linenum);
1305 if (value < 0)
1306 fatal("%.200s line %d: Bad Match condition", filename,
1307 linenum);
1308 *activep = value;
1309 break;
1310
1311 case oEscapeChar:
1312 intptr = &options->escape_char;
1313 arg = strdelim(&s);
1314 if (!arg || *arg == '\0')
1315 fatal("%.200s line %d: Missing argument.", filename, linenum);
1316 value = 0; /* To avoid compiler warning... */
1317 if (strcmp(arg, "none") == 0)
1318 value = SSH_ESCAPECHAR_NONE;
1319 else if (arg[1] == '\0')
1320 value = (u_char) arg[0];
1321 else if (arg[0] == '^' && arg[2] == 0 &&
1322 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1323 value = (u_char) arg[1] & 31;
1324 else {
1325 fatal("%.200s line %d: Bad escape character.",
1326 filename, linenum);
1327 /* NOTREACHED */
1328 value = 0; /* Avoid compiler warning. */
1329 }
1330 if (*activep && *intptr == -1)
1331 *intptr = value;
1332 break;
1333
1334 case oAddressFamily:
1335 intptr = &options->address_family;
1336 multistate_ptr = multistate_addressfamily;
1337 goto parse_multistate;
1338
1339 case oEnableSSHKeysign:
1340 intptr = &options->enable_ssh_keysign;
1341 goto parse_flag;
1342
1343 case oIdentitiesOnly:
1344 intptr = &options->identities_only;
1345 goto parse_flag;
1346
1347 case oServerAliveInterval:
1348 intptr = &options->server_alive_interval;
1349 goto parse_time;
1350
1351 case oServerAliveCountMax:
1352 intptr = &options->server_alive_count_max;
1353 goto parse_int;
1354
1355 case oSendEnv:
1356 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1357 if (strchr(arg, '=') != NULL)
1358 fatal("%s line %d: Invalid environment name.",
1359 filename, linenum);
1360 if (!*activep)
1361 continue;
1362 if (options->num_send_env >= MAX_SEND_ENV)
1363 fatal("%s line %d: too many send env.",
1364 filename, linenum);
1365 options->send_env[options->num_send_env++] =
1366 xstrdup(arg);
1367 }
1368 break;
1369
1370 case oControlPath:
1371 charptr = &options->control_path;
1372 goto parse_string;
1373
1374 case oControlMaster:
1375 intptr = &options->control_master;
1376 multistate_ptr = multistate_controlmaster;
1377 goto parse_multistate;
1378
1379 case oControlPersist:
1380 /* no/false/yes/true, or a time spec */
1381 intptr = &options->control_persist;
1382 arg = strdelim(&s);
1383 if (!arg || *arg == '\0')
1384 fatal("%.200s line %d: Missing ControlPersist"
1385 " argument.", filename, linenum);
1386 value = 0;
1387 value2 = 0; /* timeout */
1388 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1389 value = 0;
1390 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1391 value = 1;
1392 else if ((value2 = convtime(arg)) >= 0)
1393 value = 1;
1394 else
1395 fatal("%.200s line %d: Bad ControlPersist argument.",
1396 filename, linenum);
1397 if (*activep && *intptr == -1) {
1398 *intptr = value;
1399 options->control_persist_timeout = value2;
1400 }
1401 break;
1402
1403 case oHashKnownHosts:
1404 intptr = &options->hash_known_hosts;
1405 goto parse_flag;
1406
1407 case oTunnel:
1408 intptr = &options->tun_open;
1409 multistate_ptr = multistate_tunnel;
1410 goto parse_multistate;
1411
1412 case oTunnelDevice:
1413 arg = strdelim(&s);
1414 if (!arg || *arg == '\0')
1415 fatal("%.200s line %d: Missing argument.", filename, linenum);
1416 value = a2tun(arg, &value2);
1417 if (value == SSH_TUNID_ERR)
1418 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1419 if (*activep) {
1420 options->tun_local = value;
1421 options->tun_remote = value2;
1422 }
1423 break;
1424
1425 case oLocalCommand:
1426 charptr = &options->local_command;
1427 goto parse_command;
1428
1429 case oPermitLocalCommand:
1430 intptr = &options->permit_local_command;
1431 goto parse_flag;
1432
1433 case oVisualHostKey:
1434 intptr = &options->visual_host_key;
1435 goto parse_flag;
1436
1437 case oIPQoS:
1438 arg = strdelim(&s);
1439 if ((value = parse_ipqos(arg)) == -1)
1440 fatal("%s line %d: Bad IPQoS value: %s",
1441 filename, linenum, arg);
1442 arg = strdelim(&s);
1443 if (arg == NULL)
1444 value2 = value;
1445 else if ((value2 = parse_ipqos(arg)) == -1)
1446 fatal("%s line %d: Bad IPQoS value: %s",
1447 filename, linenum, arg);
1448 if (*activep) {
1449 options->ip_qos_interactive = value;
1450 options->ip_qos_bulk = value2;
1451 }
1452 break;
1453
1454 case oUseRoaming:
1455 intptr = &options->use_roaming;
1456 goto parse_flag;
1457
1458 case oRequestTTY:
1459 intptr = &options->request_tty;
1460 multistate_ptr = multistate_requesttty;
1461 goto parse_multistate;
1462
1463 case oSendVersionFirst:
1464 intptr = &options->send_version_first;
1465 goto parse_flag;
1466
1467 case oIgnoreUnknown:
1468 charptr = &options->ignored_unknown;
1469 goto parse_string;
1470
1471 case oProxyUseFdpass:
1472 intptr = &options->proxy_use_fdpass;
1473 goto parse_flag;
1474
1475 case oCanonicalDomains:
1476 value = options->num_canonical_domains != 0;
1477 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1478 valid_domain(arg, filename, linenum);
1479 if (!*activep || value)
1480 continue;
1481 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1482 fatal("%s line %d: too many hostname suffixes.",
1483 filename, linenum);
1484 options->canonical_domains[
1485 options->num_canonical_domains++] = xstrdup(arg);
1486 }
1487 break;
1488
1489 case oCanonicalizePermittedCNAMEs:
1490 value = options->num_permitted_cnames != 0;
1491 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1492 /* Either '*' for everything or 'list:list' */
1493 if (strcmp(arg, "*") == 0)
1494 arg2 = arg;
1495 else {
1496 lowercase(arg);
1497 if ((arg2 = strchr(arg, ':')) == NULL ||
1498 arg2[1] == '\0') {
1499 fatal("%s line %d: "
1500 "Invalid permitted CNAME \"%s\"",
1501 filename, linenum, arg);
1502 }
1503 *arg2 = '\0';
1504 arg2++;
1505 }
1506 if (!*activep || value)
1507 continue;
1508 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1509 fatal("%s line %d: too many permitted CNAMEs.",
1510 filename, linenum);
1511 cname = options->permitted_cnames +
1512 options->num_permitted_cnames++;
1513 cname->source_list = xstrdup(arg);
1514 cname->target_list = xstrdup(arg2);
1515 }
1516 break;
1517
1518 case oCanonicalizeHostname:
1519 intptr = &options->canonicalize_hostname;
1520 multistate_ptr = multistate_canonicalizehostname;
1521 goto parse_multistate;
1522
1523 case oCanonicalizeMaxDots:
1524 intptr = &options->canonicalize_max_dots;
1525 goto parse_int;
1526
1527 case oCanonicalizeFallbackLocal:
1528 intptr = &options->canonicalize_fallback_local;
1529 goto parse_flag;
1530
1531 case oStreamLocalBindMask:
1532 arg = strdelim(&s);
1533 if (!arg || *arg == '\0')
1534 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1535 /* Parse mode in octal format */
1536 value = strtol(arg, &endofnumber, 8);
1537 if (arg == endofnumber || value < 0 || value > 0777)
1538 fatal("%.200s line %d: Bad mask.", filename, linenum);
1539 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1540 break;
1541
1542 case oStreamLocalBindUnlink:
1543 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1544 goto parse_flag;
1545
1546 case oRevokedHostKeys:
1547 charptr = &options->revoked_host_keys;
1548 goto parse_string;
1549
1550 case oFingerprintHash:
1551 intptr = &options->fingerprint_hash;
1552 arg = strdelim(&s);
1553 if (!arg || *arg == '\0')
1554 fatal("%.200s line %d: Missing argument.",
1555 filename, linenum);
1556 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1557 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1558 filename, linenum, arg);
1559 if (*activep && *intptr == -1)
1560 *intptr = value;
1561 break;
1562
1563 case oUpdateHostkeys:
1564 intptr = &options->update_hostkeys;
1565 multistate_ptr = multistate_yesnoask;
1566 goto parse_multistate;
1567
1568 case oHostbasedKeyTypes:
1569 charptr = &options->hostbased_key_types;
1570 goto parse_keytypes;
1571
1572 case oPubkeyAcceptedKeyTypes:
1573 charptr = &options->pubkey_key_types;
1574 goto parse_keytypes;
1575
1576 case oDeprecated:
1577 debug("%s line %d: Deprecated option \"%s\"",
1578 filename, linenum, keyword);
1579 return 0;
1580
1581 case oUnsupported:
1582 error("%s line %d: Unsupported option \"%s\"",
1583 filename, linenum, keyword);
1584 return 0;
1585
1586 default:
1587 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1588 }
1589
1590 /* Check that there is no garbage at end of line. */
1591 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1592 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1593 filename, linenum, arg);
1594 }
1595 return 0;
1596 }
1597
1598
1599 /*
1600 * Reads the config file and modifies the options accordingly. Options
1601 * should already be initialized before this call. This never returns if
1602 * there is an error. If the file does not exist, this returns 0.
1603 */
1604
1605 int
1606 read_config_file(const char *filename, struct passwd *pw, const char *host,
1607 const char *original_host, Options *options, int flags)
1608 {
1609 FILE *f;
1610 char line[1024];
1611 int active, linenum;
1612 int bad_options = 0;
1613
1614 if ((f = fopen(filename, "r")) == NULL)
1615 return 0;
1616
1617 if (flags & SSHCONF_CHECKPERM) {
1618 struct stat sb;
1619
1620 if (fstat(fileno(f), &sb) == -1)
1621 fatal("fstat %s: %s", filename, strerror(errno));
1622 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1623 (sb.st_mode & 022) != 0))
1624 fatal("Bad owner or permissions on %s", filename);
1625 }
1626
1627 debug("Reading configuration data %.200s", filename);
1628
1629 /*
1630 * Mark that we are now processing the options. This flag is turned
1631 * on/off by Host specifications.
1632 */
1633 active = 1;
1634 linenum = 0;
1635 while (fgets(line, sizeof(line), f)) {
1636 /* Update line number counter. */
1637 linenum++;
1638 if (process_config_line(options, pw, host, original_host,
1639 line, filename, linenum, &active, flags) != 0)
1640 bad_options++;
1641 }
1642 fclose(f);
1643 if (bad_options > 0)
1644 fatal("%s: terminating, %d bad configuration options",
1645 filename, bad_options);
1646 return 1;
1647 }
1648
1649 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1650 int
1651 option_clear_or_none(const char *o)
1652 {
1653 return o == NULL || strcasecmp(o, "none") == 0;
1654 }
1655
1656 /*
1657 * Initializes options to special values that indicate that they have not yet
1658 * been set. Read_config_file will only set options with this value. Options
1659 * are processed in the following order: command line, user config file,
1660 * system config file. Last, fill_default_options is called.
1661 */
1662
1663 void
1664 initialize_options(Options * options)
1665 {
1666 memset(options, 'X', sizeof(*options));
1667 options->forward_agent = -1;
1668 options->forward_x11 = -1;
1669 options->forward_x11_trusted = -1;
1670 options->forward_x11_timeout = -1;
1671 options->exit_on_forward_failure = -1;
1672 options->xauth_location = NULL;
1673 options->fwd_opts.gateway_ports = -1;
1674 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1675 options->fwd_opts.streamlocal_bind_unlink = -1;
1676 options->use_privileged_port = -1;
1677 options->rsa_authentication = -1;
1678 options->pubkey_authentication = -1;
1679 options->challenge_response_authentication = -1;
1680 #if defined(KRB4) || defined(KRB5)
1681 options->kerberos_authentication = -1;
1682 #endif
1683 #if defined(AFS) || defined(KRB5)
1684 options->kerberos_tgt_passing = -1;
1685 #endif
1686 #ifdef AFS
1687 options->afs_token_passing = -1;
1688 #endif
1689 options->gss_authentication = -1;
1690 options->gss_deleg_creds = -1;
1691 options->password_authentication = -1;
1692 options->kbd_interactive_authentication = -1;
1693 options->kbd_interactive_devices = NULL;
1694 options->rhosts_rsa_authentication = -1;
1695 options->hostbased_authentication = -1;
1696 options->batch_mode = -1;
1697 options->check_host_ip = -1;
1698 options->strict_host_key_checking = -1;
1699 options->compression = -1;
1700 options->tcp_keep_alive = -1;
1701 options->compression_level = -1;
1702 options->port = -1;
1703 options->address_family = -1;
1704 options->connection_attempts = -1;
1705 options->connection_timeout = -1;
1706 options->number_of_password_prompts = -1;
1707 options->cipher = -1;
1708 options->ciphers = NULL;
1709 options->macs = NULL;
1710 options->kex_algorithms = NULL;
1711 options->hostkeyalgorithms = NULL;
1712 options->protocol = SSH_PROTO_UNKNOWN;
1713 options->num_identity_files = 0;
1714 options->hostname = NULL;
1715 options->host_key_alias = NULL;
1716 options->proxy_command = NULL;
1717 options->user = NULL;
1718 options->escape_char = -1;
1719 options->num_system_hostfiles = 0;
1720 options->num_user_hostfiles = 0;
1721 options->local_forwards = NULL;
1722 options->num_local_forwards = 0;
1723 options->remote_forwards = NULL;
1724 options->num_remote_forwards = 0;
1725 options->clear_forwardings = -1;
1726 options->log_level = SYSLOG_LEVEL_NOT_SET;
1727 options->preferred_authentications = NULL;
1728 options->bind_address = NULL;
1729 options->pkcs11_provider = NULL;
1730 options->enable_ssh_keysign = - 1;
1731 options->no_host_authentication_for_localhost = - 1;
1732 options->identities_only = - 1;
1733 options->rekey_limit = - 1;
1734 options->rekey_interval = -1;
1735 options->verify_host_key_dns = -1;
1736 options->server_alive_interval = -1;
1737 options->server_alive_count_max = -1;
1738 options->num_send_env = 0;
1739 options->control_path = NULL;
1740 options->control_master = -1;
1741 options->control_persist = -1;
1742 options->control_persist_timeout = 0;
1743 options->hash_known_hosts = -1;
1744 options->tun_open = -1;
1745 options->tun_local = -1;
1746 options->tun_remote = -1;
1747 options->local_command = NULL;
1748 options->permit_local_command = -1;
1749 options->use_roaming = -1;
1750 options->visual_host_key = -1;
1751 options->ip_qos_interactive = -1;
1752 options->ip_qos_bulk = -1;
1753 options->request_tty = -1;
1754 options->proxy_use_fdpass = -1;
1755 options->ignored_unknown = NULL;
1756 options->num_canonical_domains = 0;
1757 options->num_permitted_cnames = 0;
1758 options->canonicalize_max_dots = -1;
1759 options->canonicalize_fallback_local = -1;
1760 options->canonicalize_hostname = -1;
1761 options->revoked_host_keys = NULL;
1762 options->fingerprint_hash = -1;
1763 options->update_hostkeys = -1;
1764 options->hostbased_key_types = NULL;
1765 options->pubkey_key_types = NULL;
1766 options->none_switch = -1;
1767 options->none_enabled = -1;
1768 options->hpn_disabled = -1;
1769 options->hpn_buffer_size = -1;
1770 options->tcp_rcv_buf_poll = -1;
1771 options->tcp_rcv_buf = -1;
1772 options->send_version_first = -1;
1773 }
1774
1775 /*
1776 * A petite version of fill_default_options() that just fills the options
1777 * needed for hostname canonicalization to proceed.
1778 */
1779 void
1780 fill_default_options_for_canonicalization(Options *options)
1781 {
1782 if (options->canonicalize_max_dots == -1)
1783 options->canonicalize_max_dots = 1;
1784 if (options->canonicalize_fallback_local == -1)
1785 options->canonicalize_fallback_local = 1;
1786 if (options->canonicalize_hostname == -1)
1787 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1788 }
1789
1790 /*
1791 * Called after processing other sources of option data, this fills those
1792 * options for which no value has been specified with their default values.
1793 */
1794 void
1795 fill_default_options(Options * options)
1796 {
1797 if (options->forward_agent == -1)
1798 options->forward_agent = 0;
1799 if (options->forward_x11 == -1)
1800 options->forward_x11 = 0;
1801 if (options->forward_x11_trusted == -1)
1802 options->forward_x11_trusted = 0;
1803 if (options->forward_x11_timeout == -1)
1804 options->forward_x11_timeout = 1200;
1805 if (options->exit_on_forward_failure == -1)
1806 options->exit_on_forward_failure = 0;
1807 if (options->xauth_location == NULL)
1808 options->xauth_location = __UNCONST(_PATH_XAUTH);
1809 if (options->fwd_opts.gateway_ports == -1)
1810 options->fwd_opts.gateway_ports = 0;
1811 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1812 options->fwd_opts.streamlocal_bind_mask = 0177;
1813 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1814 options->fwd_opts.streamlocal_bind_unlink = 0;
1815 if (options->use_privileged_port == -1)
1816 options->use_privileged_port = 0;
1817 if (options->rsa_authentication == -1)
1818 options->rsa_authentication = 1;
1819 if (options->pubkey_authentication == -1)
1820 options->pubkey_authentication = 1;
1821 if (options->challenge_response_authentication == -1)
1822 options->challenge_response_authentication = 1;
1823 #if defined(KRB4) || defined(KRB5)
1824 if (options->kerberos_authentication == -1)
1825 options->kerberos_authentication = 1;
1826 #endif
1827 #if defined(AFS) || defined(KRB5)
1828 if (options->kerberos_tgt_passing == -1)
1829 options->kerberos_tgt_passing = 1;
1830 #endif
1831 #ifdef AFS
1832 if (options->afs_token_passing == -1)
1833 options->afs_token_passing = 1;
1834 #endif
1835 if (options->gss_authentication == -1)
1836 options->gss_authentication = 0;
1837 if (options->gss_deleg_creds == -1)
1838 options->gss_deleg_creds = 0;
1839 if (options->password_authentication == -1)
1840 options->password_authentication = 1;
1841 if (options->kbd_interactive_authentication == -1)
1842 options->kbd_interactive_authentication = 1;
1843 if (options->rhosts_rsa_authentication == -1)
1844 options->rhosts_rsa_authentication = 0;
1845 if (options->hostbased_authentication == -1)
1846 options->hostbased_authentication = 0;
1847 if (options->batch_mode == -1)
1848 options->batch_mode = 0;
1849 if (options->check_host_ip == -1)
1850 options->check_host_ip = 1;
1851 if (options->strict_host_key_checking == -1)
1852 options->strict_host_key_checking = 2; /* 2 is default */
1853 if (options->compression == -1)
1854 options->compression = 0;
1855 if (options->tcp_keep_alive == -1)
1856 options->tcp_keep_alive = 1;
1857 if (options->compression_level == -1)
1858 options->compression_level = 6;
1859 if (options->port == -1)
1860 options->port = 0; /* Filled in ssh_connect. */
1861 if (options->address_family == -1)
1862 options->address_family = AF_UNSPEC;
1863 if (options->connection_attempts == -1)
1864 options->connection_attempts = 1;
1865 if (options->number_of_password_prompts == -1)
1866 options->number_of_password_prompts = 3;
1867 /* Selected in ssh_login(). */
1868 if (options->cipher == -1)
1869 options->cipher = SSH_CIPHER_NOT_SET;
1870 /* options->hostkeyalgorithms, default set in myproposals.h */
1871 if (options->protocol == SSH_PROTO_UNKNOWN)
1872 options->protocol = SSH_PROTO_2;
1873 if (options->num_identity_files == 0) {
1874 if (options->protocol & SSH_PROTO_1) {
1875 add_identity_file(options, "~/",
1876 _PATH_SSH_CLIENT_IDENTITY, 0);
1877 }
1878 if (options->protocol & SSH_PROTO_2) {
1879 add_identity_file(options, "~/",
1880 _PATH_SSH_CLIENT_ID_RSA, 0);
1881 add_identity_file(options, "~/",
1882 _PATH_SSH_CLIENT_ID_DSA, 0);
1883 add_identity_file(options, "~/",
1884 _PATH_SSH_CLIENT_ID_ECDSA, 0);
1885 add_identity_file(options, "~/",
1886 _PATH_SSH_CLIENT_ID_ED25519, 0);
1887 }
1888 }
1889 if (options->escape_char == -1)
1890 options->escape_char = '~';
1891 if (options->num_system_hostfiles == 0) {
1892 options->system_hostfiles[options->num_system_hostfiles++] =
1893 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1894 options->system_hostfiles[options->num_system_hostfiles++] =
1895 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1896 }
1897 if (options->num_user_hostfiles == 0) {
1898 options->user_hostfiles[options->num_user_hostfiles++] =
1899 xstrdup(_PATH_SSH_USER_HOSTFILE);
1900 options->user_hostfiles[options->num_user_hostfiles++] =
1901 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1902 }
1903 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1904 options->log_level = SYSLOG_LEVEL_INFO;
1905 if (options->clear_forwardings == 1)
1906 clear_forwardings(options);
1907 if (options->no_host_authentication_for_localhost == - 1)
1908 options->no_host_authentication_for_localhost = 0;
1909 if (options->identities_only == -1)
1910 options->identities_only = 0;
1911 if (options->enable_ssh_keysign == -1)
1912 options->enable_ssh_keysign = 0;
1913 if (options->rekey_limit == -1)
1914 options->rekey_limit = 0;
1915 if (options->rekey_interval == -1)
1916 options->rekey_interval = 0;
1917 if (options->verify_host_key_dns == -1)
1918 options->verify_host_key_dns = 0;
1919 if (options->server_alive_interval == -1)
1920 options->server_alive_interval = 0;
1921 if (options->server_alive_count_max == -1)
1922 options->server_alive_count_max = 3;
1923 if (options->none_switch == -1)
1924 options->none_switch = 0;
1925 if (options->hpn_disabled == -1)
1926 options->hpn_disabled = 0;
1927 if (options->hpn_buffer_size > -1)
1928 {
1929 /* if a user tries to set the size to 0 set it to 1KB */
1930 if (options->hpn_buffer_size == 0)
1931 options->hpn_buffer_size = 1024;
1932 /*limit the buffer to 64MB*/
1933 if (options->hpn_buffer_size > 65536)
1934 {
1935 options->hpn_buffer_size = 65536*1024;
1936 debug("User requested buffer larger than 64MB. Request reverted to 64MB");
1937 }
1938 debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1939 }
1940 if (options->tcp_rcv_buf == 0)
1941 options->tcp_rcv_buf = 1;
1942 if (options->tcp_rcv_buf > -1)
1943 options->tcp_rcv_buf *=1024;
1944 if (options->tcp_rcv_buf_poll == -1)
1945 options->tcp_rcv_buf_poll = 1;
1946 if (options->control_master == -1)
1947 options->control_master = 0;
1948 if (options->control_persist == -1) {
1949 options->control_persist = 0;
1950 options->control_persist_timeout = 0;
1951 }
1952 if (options->hash_known_hosts == -1)
1953 options->hash_known_hosts = 0;
1954 if (options->tun_open == -1)
1955 options->tun_open = SSH_TUNMODE_NO;
1956 if (options->tun_local == -1)
1957 options->tun_local = SSH_TUNID_ANY;
1958 if (options->tun_remote == -1)
1959 options->tun_remote = SSH_TUNID_ANY;
1960 if (options->permit_local_command == -1)
1961 options->permit_local_command = 0;
1962 if (options->use_roaming == -1)
1963 options->use_roaming = 1;
1964 if (options->visual_host_key == -1)
1965 options->visual_host_key = 0;
1966 if (options->ip_qos_interactive == -1)
1967 options->ip_qos_interactive = IPTOS_LOWDELAY;
1968 if (options->ip_qos_bulk == -1)
1969 options->ip_qos_bulk = IPTOS_THROUGHPUT;
1970 if (options->request_tty == -1)
1971 options->request_tty = REQUEST_TTY_AUTO;
1972 if (options->proxy_use_fdpass == -1)
1973 options->proxy_use_fdpass = 0;
1974 if (options->canonicalize_max_dots == -1)
1975 options->canonicalize_max_dots = 1;
1976 if (options->canonicalize_fallback_local == -1)
1977 options->canonicalize_fallback_local = 1;
1978 if (options->canonicalize_hostname == -1)
1979 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1980 if (options->fingerprint_hash == -1)
1981 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
1982 if (options->update_hostkeys == -1)
1983 options->update_hostkeys = 0;
1984 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
1985 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
1986 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
1987 kex_assemble_names(KEX_DEFAULT_PK_ALG,
1988 &options->hostbased_key_types) != 0 ||
1989 kex_assemble_names(KEX_DEFAULT_PK_ALG,
1990 &options->pubkey_key_types) != 0)
1991 fatal("%s: kex_assemble_names failed", __func__);
1992
1993 if (options->send_version_first == -1)
1994 options->send_version_first = 1;
1995 #define CLEAR_ON_NONE(v) \
1996 do { \
1997 if (option_clear_or_none(v)) { \
1998 free(v); \
1999 v = NULL; \
2000 } \
2001 } while(0)
2002 CLEAR_ON_NONE(options->local_command);
2003 CLEAR_ON_NONE(options->proxy_command);
2004 CLEAR_ON_NONE(options->control_path);
2005 CLEAR_ON_NONE(options->revoked_host_keys);
2006 /* options->user will be set in the main program if appropriate */
2007 /* options->hostname will be set in the main program if appropriate */
2008 /* options->host_key_alias should not be set by default */
2009 /* options->preferred_authentications will be set in ssh */
2010 }
2011
2012 struct fwdarg {
2013 char *arg;
2014 int ispath;
2015 };
2016
2017 /*
2018 * parse_fwd_field
2019 * parses the next field in a port forwarding specification.
2020 * sets fwd to the parsed field and advances p past the colon
2021 * or sets it to NULL at end of string.
2022 * returns 0 on success, else non-zero.
2023 */
2024 static int
2025 parse_fwd_field(char **p, struct fwdarg *fwd)
2026 {
2027 char *ep, *cp = *p;
2028 int ispath = 0;
2029
2030 if (*cp == '\0') {
2031 *p = NULL;
2032 return -1; /* end of string */
2033 }
2034
2035 /*
2036 * A field escaped with square brackets is used literally.
2037 * XXX - allow ']' to be escaped via backslash?
2038 */
2039 if (*cp == '[') {
2040 /* find matching ']' */
2041 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2042 if (*ep == '/')
2043 ispath = 1;
2044 }
2045 /* no matching ']' or not at end of field. */
2046 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2047 return -1;
2048 /* NUL terminate the field and advance p past the colon */
2049 *ep++ = '\0';
2050 if (*ep != '\0')
2051 *ep++ = '\0';
2052 fwd->arg = cp + 1;
2053 fwd->ispath = ispath;
2054 *p = ep;
2055 return 0;
2056 }
2057
2058 for (cp = *p; *cp != '\0'; cp++) {
2059 switch (*cp) {
2060 case '\\':
2061 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2062 if (*cp == '\0')
2063 return -1;
2064 break;
2065 case '/':
2066 ispath = 1;
2067 break;
2068 case ':':
2069 *cp++ = '\0';
2070 goto done;
2071 }
2072 }
2073 done:
2074 fwd->arg = *p;
2075 fwd->ispath = ispath;
2076 *p = cp;
2077 return 0;
2078 }
2079
2080 /*
2081 * parse_forward
2082 * parses a string containing a port forwarding specification of the form:
2083 * dynamicfwd == 0
2084 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2085 * listenpath:connectpath
2086 * dynamicfwd == 1
2087 * [listenhost:]listenport
2088 * returns number of arguments parsed or zero on error
2089 */
2090 int
2091 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2092 {
2093 struct fwdarg fwdargs[4];
2094 char *p, *cp;
2095 int i;
2096
2097 memset(fwd, 0, sizeof(*fwd));
2098 memset(fwdargs, 0, sizeof(fwdargs));
2099
2100 cp = p = xstrdup(fwdspec);
2101
2102 /* skip leading spaces */
2103 while (isspace((u_char)*cp))
2104 cp++;
2105
2106 for (i = 0; i < 4; ++i) {
2107 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2108 break;
2109 }
2110
2111 /* Check for trailing garbage */
2112 if (cp != NULL && *cp != '\0') {
2113 i = 0; /* failure */
2114 }
2115
2116 switch (i) {
2117 case 1:
2118 if (fwdargs[0].ispath) {
2119 fwd->listen_path = xstrdup(fwdargs[0].arg);
2120 fwd->listen_port = PORT_STREAMLOCAL;
2121 } else {
2122 fwd->listen_host = NULL;
2123 fwd->listen_port = a2port(fwdargs[0].arg);
2124 }
2125 fwd->connect_host = xstrdup("socks");
2126 break;
2127
2128 case 2:
2129 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2130 fwd->listen_path = xstrdup(fwdargs[0].arg);
2131 fwd->listen_port = PORT_STREAMLOCAL;
2132 fwd->connect_path = xstrdup(fwdargs[1].arg);
2133 fwd->connect_port = PORT_STREAMLOCAL;
2134 } else if (fwdargs[1].ispath) {
2135 fwd->listen_host = NULL;
2136 fwd->listen_port = a2port(fwdargs[0].arg);
2137 fwd->connect_path = xstrdup(fwdargs[1].arg);
2138 fwd->connect_port = PORT_STREAMLOCAL;
2139 } else {
2140 fwd->listen_host = xstrdup(fwdargs[0].arg);
2141 fwd->listen_port = a2port(fwdargs[1].arg);
2142 fwd->connect_host = xstrdup("socks");
2143 }
2144 break;
2145
2146 case 3:
2147 if (fwdargs[0].ispath) {
2148 fwd->listen_path = xstrdup(fwdargs[0].arg);
2149 fwd->listen_port = PORT_STREAMLOCAL;
2150 fwd->connect_host = xstrdup(fwdargs[1].arg);
2151 fwd->connect_port = a2port(fwdargs[2].arg);
2152 } else if (fwdargs[2].ispath) {
2153 fwd->listen_host = xstrdup(fwdargs[0].arg);
2154 fwd->listen_port = a2port(fwdargs[1].arg);
2155 fwd->connect_path = xstrdup(fwdargs[2].arg);
2156 fwd->connect_port = PORT_STREAMLOCAL;
2157 } else {
2158 fwd->listen_host = NULL;
2159 fwd->listen_port = a2port(fwdargs[0].arg);
2160 fwd->connect_host = xstrdup(fwdargs[1].arg);
2161 fwd->connect_port = a2port(fwdargs[2].arg);
2162 }
2163 break;
2164
2165 case 4:
2166 fwd->listen_host = xstrdup(fwdargs[0].arg);
2167 fwd->listen_port = a2port(fwdargs[1].arg);
2168 fwd->connect_host = xstrdup(fwdargs[2].arg);
2169 fwd->connect_port = a2port(fwdargs[3].arg);
2170 break;
2171 default:
2172 i = 0; /* failure */
2173 }
2174
2175 free(p);
2176
2177 if (dynamicfwd) {
2178 if (!(i == 1 || i == 2))
2179 goto fail_free;
2180 } else {
2181 if (!(i == 3 || i == 4)) {
2182 if (fwd->connect_path == NULL &&
2183 fwd->listen_path == NULL)
2184 goto fail_free;
2185 }
2186 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2187 goto fail_free;
2188 }
2189
2190 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2191 (!remotefwd && fwd->listen_port == 0))
2192 goto fail_free;
2193 if (fwd->connect_host != NULL &&
2194 strlen(fwd->connect_host) >= NI_MAXHOST)
2195 goto fail_free;
2196 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2197 if (fwd->connect_path != NULL &&
2198 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2199 goto fail_free;
2200 if (fwd->listen_host != NULL &&
2201 strlen(fwd->listen_host) >= NI_MAXHOST)
2202 goto fail_free;
2203 if (fwd->listen_path != NULL &&
2204 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2205 goto fail_free;
2206
2207 return (i);
2208
2209 fail_free:
2210 free(fwd->connect_host);
2211 fwd->connect_host = NULL;
2212 free(fwd->connect_path);
2213 fwd->connect_path = NULL;
2214 free(fwd->listen_host);
2215 fwd->listen_host = NULL;
2216 free(fwd->listen_path);
2217 fwd->listen_path = NULL;
2218 return (0);
2219 }
2220
2221 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2222 static const char *
2223 fmt_multistate_int(int val, const struct multistate *m)
2224 {
2225 u_int i;
2226
2227 for (i = 0; m[i].key != NULL; i++) {
2228 if (m[i].value == val)
2229 return m[i].key;
2230 }
2231 return "UNKNOWN";
2232 }
2233
2234 static const char *
2235 fmt_intarg(OpCodes code, int val)
2236 {
2237 if (val == -1)
2238 return "unset";
2239 switch (code) {
2240 case oAddressFamily:
2241 return fmt_multistate_int(val, multistate_addressfamily);
2242 case oVerifyHostKeyDNS:
2243 case oStrictHostKeyChecking:
2244 case oUpdateHostkeys:
2245 return fmt_multistate_int(val, multistate_yesnoask);
2246 case oControlMaster:
2247 return fmt_multistate_int(val, multistate_controlmaster);
2248 case oTunnel:
2249 return fmt_multistate_int(val, multistate_tunnel);
2250 case oRequestTTY:
2251 return fmt_multistate_int(val, multistate_requesttty);
2252 case oCanonicalizeHostname:
2253 return fmt_multistate_int(val, multistate_canonicalizehostname);
2254 case oFingerprintHash:
2255 return ssh_digest_alg_name(val);
2256 case oProtocol:
2257 switch (val) {
2258 case SSH_PROTO_1:
2259 return "1";
2260 case SSH_PROTO_2:
2261 return "2";
2262 case (SSH_PROTO_1|SSH_PROTO_2):
2263 return "2,1";
2264 default:
2265 return "UNKNOWN";
2266 }
2267 default:
2268 switch (val) {
2269 case 0:
2270 return "no";
2271 case 1:
2272 return "yes";
2273 default:
2274 return "UNKNOWN";
2275 }
2276 }
2277 }
2278
2279 static const char *
2280 lookup_opcode_name(OpCodes code)
2281 {
2282 u_int i;
2283
2284 for (i = 0; keywords[i].name != NULL; i++)
2285 if (keywords[i].opcode == code)
2286 return(keywords[i].name);
2287 return "UNKNOWN";
2288 }
2289
2290 static void
2291 dump_cfg_int(OpCodes code, int val)
2292 {
2293 printf("%s %d\n", lookup_opcode_name(code), val);
2294 }
2295
2296 static void
2297 dump_cfg_fmtint(OpCodes code, int val)
2298 {
2299 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2300 }
2301
2302 static void
2303 dump_cfg_string(OpCodes code, const char *val)
2304 {
2305 if (val == NULL)
2306 return;
2307 printf("%s %s\n", lookup_opcode_name(code), val);
2308 }
2309
2310 static void
2311 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2312 {
2313 u_int i;
2314
2315 for (i = 0; i < count; i++)
2316 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2317 }
2318
2319 static void
2320 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2321 {
2322 u_int i;
2323
2324 printf("%s", lookup_opcode_name(code));
2325 for (i = 0; i < count; i++)
2326 printf(" %s", vals[i]);
2327 printf("\n");
2328 }
2329
2330 static void
2331 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2332 {
2333 const struct Forward *fwd;
2334 u_int i;
2335
2336 /* oDynamicForward */
2337 for (i = 0; i < count; i++) {
2338 fwd = &fwds[i];
2339 if (code == oDynamicForward &&
2340 strcmp(fwd->connect_host, "socks") != 0)
2341 continue;
2342 if (code == oLocalForward &&
2343 strcmp(fwd->connect_host, "socks") == 0)
2344 continue;
2345 printf("%s", lookup_opcode_name(code));
2346 if (fwd->listen_port == PORT_STREAMLOCAL)
2347 printf(" %s", fwd->listen_path);
2348 else if (fwd->listen_host == NULL)
2349 printf(" %d", fwd->listen_port);
2350 else {
2351 printf(" [%s]:%d",
2352 fwd->listen_host, fwd->listen_port);
2353 }
2354 if (code != oDynamicForward) {
2355 if (fwd->connect_port == PORT_STREAMLOCAL)
2356 printf(" %s", fwd->connect_path);
2357 else if (fwd->connect_host == NULL)
2358 printf(" %d", fwd->connect_port);
2359 else {
2360 printf(" [%s]:%d",
2361 fwd->connect_host, fwd->connect_port);
2362 }
2363 }
2364 printf("\n");
2365 }
2366 }
2367
2368 void
2369 dump_client_config(Options *o, const char *host)
2370 {
2371 int i;
2372 char vbuf[5];
2373
2374 /* Most interesting options first: user, host, port */
2375 dump_cfg_string(oUser, o->user);
2376 dump_cfg_string(oHostName, host);
2377 dump_cfg_int(oPort, o->port);
2378
2379 /* Flag options */
2380 dump_cfg_fmtint(oAddressFamily, o->address_family);
2381 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2382 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2383 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2384 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2385 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2386 dump_cfg_fmtint(oCompression, o->compression);
2387 dump_cfg_fmtint(oControlMaster, o->control_master);
2388 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2389 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2390 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2391 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2392 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2393 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2394 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2395 #ifdef GSSAPI
2396 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2397 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2398 #endif /* GSSAPI */
2399 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2400 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2401 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2402 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2403 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2404 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2405 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2406 dump_cfg_fmtint(oProtocol, o->protocol);
2407 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2408 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2409 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2410 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2411 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2412 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2413 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2414 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2415 dump_cfg_fmtint(oTunnel, o->tun_open);
2416 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2417 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2418 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2419 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2420
2421 /* Integer options */
2422 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2423 dump_cfg_int(oCompressionLevel, o->compression_level);
2424 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2425 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2426 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2427 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2428 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2429
2430 /* String options */
2431 dump_cfg_string(oBindAddress, o->bind_address);
2432 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2433 dump_cfg_string(oControlPath, o->control_path);
2434 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2435 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2436 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2437 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2438 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2439 dump_cfg_string(oLocalCommand, o->local_command);
2440 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2441 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2442 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2443 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2444 dump_cfg_string(oProxyCommand, o->proxy_command);
2445 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2446 dump_cfg_string(oXAuthLocation, o->xauth_location);
2447
2448 /* Forwards */
2449 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2450 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2451 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2452
2453 /* String array options */
2454 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2455 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2456 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2457 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2458 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2459
2460 /* Special cases */
2461
2462 /* oConnectTimeout */
2463 if (o->connection_timeout == -1)
2464 printf("connecttimeout none\n");
2465 else
2466 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2467
2468 /* oTunnelDevice */
2469 printf("tunneldevice");
2470 if (o->tun_local == SSH_TUNID_ANY)
2471 printf(" any");
2472 else
2473 printf(" %d", o->tun_local);
2474 if (o->tun_remote == SSH_TUNID_ANY)
2475 printf(":any");
2476 else
2477 printf(":%d", o->tun_remote);
2478 printf("\n");
2479
2480 /* oCanonicalizePermittedCNAMEs */
2481 if ( o->num_permitted_cnames > 0) {
2482 printf("canonicalizePermittedcnames");
2483 for (i = 0; i < o->num_permitted_cnames; i++) {
2484 printf(" %s:%s", o->permitted_cnames[i].source_list,
2485 o->permitted_cnames[i].target_list);
2486 }
2487 printf("\n");
2488 }
2489
2490 /* oCipher */
2491 if (o->cipher != SSH_CIPHER_NOT_SET)
2492 printf("Cipher %s\n", cipher_name(o->cipher));
2493
2494 /* oControlPersist */
2495 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2496 dump_cfg_fmtint(oControlPersist, o->control_persist);
2497 else
2498 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2499
2500 /* oEscapeChar */
2501 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2502 printf("escapechar none\n");
2503 else {
2504 vis(vbuf, o->escape_char, VIS_WHITE, 0);
2505 printf("escapechar %s\n", vbuf);
2506 }
2507
2508 /* oIPQoS */
2509 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2510 printf("%s\n", iptos2str(o->ip_qos_bulk));
2511
2512 /* oRekeyLimit */
2513 printf("rekeylimit %lld %d\n",
2514 (long long)o->rekey_limit, o->rekey_interval);
2515
2516 /* oStreamLocalBindMask */
2517 printf("streamlocalbindmask 0%o\n",
2518 o->fwd_opts.streamlocal_bind_mask);
2519 }
2520