- (dtucker) [openbsd-compat/port-linux.c] Check is_selinux_enabled for exact
[openssh-git.git] / readconf.c
blob98ce3017fca44609a3690bae69ed0a9921a30b93
1 /* $OpenBSD: readconf.c,v 1.188 2010/08/31 11:54:45 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.
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".
15 #include "includes.h"
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/socket.h>
21 #include <netinet/in.h>
23 #include <ctype.h>
24 #include <errno.h>
25 #include <netdb.h>
26 #include <signal.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
32 #include "xmalloc.h"
33 #include "ssh.h"
34 #include "compat.h"
35 #include "cipher.h"
36 #include "pathnames.h"
37 #include "log.h"
38 #include "key.h"
39 #include "readconf.h"
40 #include "match.h"
41 #include "misc.h"
42 #include "buffer.h"
43 #include "kex.h"
44 #include "mac.h"
46 /* Format of the configuration file:
48 # Configuration data is parsed as follows:
49 # 1. command line options
50 # 2. user-specific file
51 # 3. system-wide file
52 # Any configuration value is only changed the first time it is set.
53 # Thus, host-specific definitions should be at the beginning of the
54 # configuration file, and defaults at the end.
56 # Host-specific declarations. These may override anything above. A single
57 # host may match multiple declarations; these are processed in the order
58 # that they are given in.
60 Host *.ngs.fi ngs.fi
61 User foo
63 Host fake.com
64 HostName another.host.name.real.org
65 User blaah
66 Port 34289
67 ForwardX11 no
68 ForwardAgent no
70 Host books.com
71 RemoteForward 9999 shadows.cs.hut.fi:9999
72 Cipher 3des
74 Host fascist.blob.com
75 Port 23123
76 User tylonen
77 PasswordAuthentication no
79 Host puukko.hut.fi
80 User t35124p
81 ProxyCommand ssh-proxy %h %p
83 Host *.fr
84 PublicKeyAuthentication no
86 Host *.su
87 Cipher none
88 PasswordAuthentication no
90 Host vpn.fake.com
91 Tunnel yes
92 TunnelDevice 3
94 # Defaults for various options
95 Host *
96 ForwardAgent no
97 ForwardX11 no
98 PasswordAuthentication yes
99 RSAAuthentication yes
100 RhostsRSAAuthentication yes
101 StrictHostKeyChecking yes
102 TcpKeepAlive no
103 IdentityFile ~/.ssh/identity
104 Port 22
105 EscapeChar ~
109 /* Keyword tokens. */
111 typedef enum {
112 oBadOption,
113 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
114 oGatewayPorts, oExitOnForwardFailure,
115 oPasswordAuthentication, oRSAAuthentication,
116 oChallengeResponseAuthentication, oXAuthLocation,
117 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
118 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
119 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
120 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
121 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
122 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
123 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
124 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
125 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
126 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
127 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
128 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
129 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
130 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
131 oSendEnv, oControlPath, oControlMaster, oControlPersist,
132 oHashKnownHosts,
133 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
134 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
135 oDeprecated, oUnsupported
136 } OpCodes;
138 /* Textual representations of the tokens. */
140 static struct {
141 const char *name;
142 OpCodes opcode;
143 } keywords[] = {
144 { "forwardagent", oForwardAgent },
145 { "forwardx11", oForwardX11 },
146 { "forwardx11trusted", oForwardX11Trusted },
147 { "forwardx11timeout", oForwardX11Timeout },
148 { "exitonforwardfailure", oExitOnForwardFailure },
149 { "xauthlocation", oXAuthLocation },
150 { "gatewayports", oGatewayPorts },
151 { "useprivilegedport", oUsePrivilegedPort },
152 { "rhostsauthentication", oDeprecated },
153 { "passwordauthentication", oPasswordAuthentication },
154 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
155 { "kbdinteractivedevices", oKbdInteractiveDevices },
156 { "rsaauthentication", oRSAAuthentication },
157 { "pubkeyauthentication", oPubkeyAuthentication },
158 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
159 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
160 { "hostbasedauthentication", oHostbasedAuthentication },
161 { "challengeresponseauthentication", oChallengeResponseAuthentication },
162 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
163 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
164 { "kerberosauthentication", oUnsupported },
165 { "kerberostgtpassing", oUnsupported },
166 { "afstokenpassing", oUnsupported },
167 #if defined(GSSAPI)
168 { "gssapiauthentication", oGssAuthentication },
169 { "gssapidelegatecredentials", oGssDelegateCreds },
170 #else
171 { "gssapiauthentication", oUnsupported },
172 { "gssapidelegatecredentials", oUnsupported },
173 #endif
174 { "fallbacktorsh", oDeprecated },
175 { "usersh", oDeprecated },
176 { "identityfile", oIdentityFile },
177 { "identityfile2", oIdentityFile }, /* obsolete */
178 { "identitiesonly", oIdentitiesOnly },
179 { "hostname", oHostName },
180 { "hostkeyalias", oHostKeyAlias },
181 { "proxycommand", oProxyCommand },
182 { "port", oPort },
183 { "cipher", oCipher },
184 { "ciphers", oCiphers },
185 { "macs", oMacs },
186 { "protocol", oProtocol },
187 { "remoteforward", oRemoteForward },
188 { "localforward", oLocalForward },
189 { "user", oUser },
190 { "host", oHost },
191 { "escapechar", oEscapeChar },
192 { "globalknownhostsfile", oGlobalKnownHostsFile },
193 { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, /* obsolete */
194 { "userknownhostsfile", oUserKnownHostsFile },
195 { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */
196 { "connectionattempts", oConnectionAttempts },
197 { "batchmode", oBatchMode },
198 { "checkhostip", oCheckHostIP },
199 { "stricthostkeychecking", oStrictHostKeyChecking },
200 { "compression", oCompression },
201 { "compressionlevel", oCompressionLevel },
202 { "tcpkeepalive", oTCPKeepAlive },
203 { "keepalive", oTCPKeepAlive }, /* obsolete */
204 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
205 { "loglevel", oLogLevel },
206 { "dynamicforward", oDynamicForward },
207 { "preferredauthentications", oPreferredAuthentications },
208 { "hostkeyalgorithms", oHostKeyAlgorithms },
209 { "bindaddress", oBindAddress },
210 #ifdef ENABLE_PKCS11
211 { "smartcarddevice", oPKCS11Provider },
212 { "pkcs11provider", oPKCS11Provider },
213 #else
214 { "smartcarddevice", oUnsupported },
215 { "pkcs11provider", oUnsupported },
216 #endif
217 { "clearallforwardings", oClearAllForwardings },
218 { "enablesshkeysign", oEnableSSHKeysign },
219 { "verifyhostkeydns", oVerifyHostKeyDNS },
220 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
221 { "rekeylimit", oRekeyLimit },
222 { "connecttimeout", oConnectTimeout },
223 { "addressfamily", oAddressFamily },
224 { "serveraliveinterval", oServerAliveInterval },
225 { "serveralivecountmax", oServerAliveCountMax },
226 { "sendenv", oSendEnv },
227 { "controlpath", oControlPath },
228 { "controlmaster", oControlMaster },
229 { "controlpersist", oControlPersist },
230 { "hashknownhosts", oHashKnownHosts },
231 { "tunnel", oTunnel },
232 { "tunneldevice", oTunnelDevice },
233 { "localcommand", oLocalCommand },
234 { "permitlocalcommand", oPermitLocalCommand },
235 { "visualhostkey", oVisualHostKey },
236 { "useroaming", oUseRoaming },
237 #ifdef JPAKE
238 { "zeroknowledgepasswordauthentication",
239 oZeroKnowledgePasswordAuthentication },
240 #else
241 { "zeroknowledgepasswordauthentication", oUnsupported },
242 #endif
244 { NULL, oBadOption }
248 * Adds a local TCP/IP port forward to options. Never returns if there is an
249 * error.
252 void
253 add_local_forward(Options *options, const Forward *newfwd)
255 Forward *fwd;
256 #ifndef NO_IPPORT_RESERVED_CONCEPT
257 extern uid_t original_real_uid;
258 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
259 fatal("Privileged ports can only be forwarded by root.");
260 #endif
261 options->local_forwards = xrealloc(options->local_forwards,
262 options->num_local_forwards + 1,
263 sizeof(*options->local_forwards));
264 fwd = &options->local_forwards[options->num_local_forwards++];
266 fwd->listen_host = newfwd->listen_host;
267 fwd->listen_port = newfwd->listen_port;
268 fwd->connect_host = newfwd->connect_host;
269 fwd->connect_port = newfwd->connect_port;
273 * Adds a remote TCP/IP port forward to options. Never returns if there is
274 * an error.
277 void
278 add_remote_forward(Options *options, const Forward *newfwd)
280 Forward *fwd;
282 options->remote_forwards = xrealloc(options->remote_forwards,
283 options->num_remote_forwards + 1,
284 sizeof(*options->remote_forwards));
285 fwd = &options->remote_forwards[options->num_remote_forwards++];
287 fwd->listen_host = newfwd->listen_host;
288 fwd->listen_port = newfwd->listen_port;
289 fwd->connect_host = newfwd->connect_host;
290 fwd->connect_port = newfwd->connect_port;
291 fwd->allocated_port = 0;
294 static void
295 clear_forwardings(Options *options)
297 int i;
299 for (i = 0; i < options->num_local_forwards; i++) {
300 if (options->local_forwards[i].listen_host != NULL)
301 xfree(options->local_forwards[i].listen_host);
302 xfree(options->local_forwards[i].connect_host);
304 if (options->num_local_forwards > 0) {
305 xfree(options->local_forwards);
306 options->local_forwards = NULL;
308 options->num_local_forwards = 0;
309 for (i = 0; i < options->num_remote_forwards; i++) {
310 if (options->remote_forwards[i].listen_host != NULL)
311 xfree(options->remote_forwards[i].listen_host);
312 xfree(options->remote_forwards[i].connect_host);
314 if (options->num_remote_forwards > 0) {
315 xfree(options->remote_forwards);
316 options->remote_forwards = NULL;
318 options->num_remote_forwards = 0;
319 options->tun_open = SSH_TUNMODE_NO;
323 * Returns the number of the token pointed to by cp or oBadOption.
326 static OpCodes
327 parse_token(const char *cp, const char *filename, int linenum)
329 u_int i;
331 for (i = 0; keywords[i].name; i++)
332 if (strcasecmp(cp, keywords[i].name) == 0)
333 return keywords[i].opcode;
335 error("%s: line %d: Bad configuration option: %s",
336 filename, linenum, cp);
337 return oBadOption;
341 * Processes a single option line as used in the configuration files. This
342 * only sets those values that have not already been set.
344 #define WHITESPACE " \t\r\n"
347 process_config_line(Options *options, const char *host,
348 char *line, const char *filename, int linenum,
349 int *activep)
351 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
352 int opcode, *intptr, value, value2, scale;
353 LogLevel *log_level_ptr;
354 long long orig, val64;
355 size_t len;
356 Forward fwd;
358 /* Strip trailing whitespace */
359 for (len = strlen(line) - 1; len > 0; len--) {
360 if (strchr(WHITESPACE, line[len]) == NULL)
361 break;
362 line[len] = '\0';
365 s = line;
366 /* Get the keyword. (Each line is supposed to begin with a keyword). */
367 if ((keyword = strdelim(&s)) == NULL)
368 return 0;
369 /* Ignore leading whitespace. */
370 if (*keyword == '\0')
371 keyword = strdelim(&s);
372 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
373 return 0;
375 opcode = parse_token(keyword, filename, linenum);
377 switch (opcode) {
378 case oBadOption:
379 /* don't panic, but count bad options */
380 return -1;
381 /* NOTREACHED */
382 case oConnectTimeout:
383 intptr = &options->connection_timeout;
384 parse_time:
385 arg = strdelim(&s);
386 if (!arg || *arg == '\0')
387 fatal("%s line %d: missing time value.",
388 filename, linenum);
389 if ((value = convtime(arg)) == -1)
390 fatal("%s line %d: invalid time value.",
391 filename, linenum);
392 if (*activep && *intptr == -1)
393 *intptr = value;
394 break;
396 case oForwardAgent:
397 intptr = &options->forward_agent;
398 parse_flag:
399 arg = strdelim(&s);
400 if (!arg || *arg == '\0')
401 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
402 value = 0; /* To avoid compiler warning... */
403 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
404 value = 1;
405 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
406 value = 0;
407 else
408 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
409 if (*activep && *intptr == -1)
410 *intptr = value;
411 break;
413 case oForwardX11:
414 intptr = &options->forward_x11;
415 goto parse_flag;
417 case oForwardX11Trusted:
418 intptr = &options->forward_x11_trusted;
419 goto parse_flag;
421 case oForwardX11Timeout:
422 intptr = &options->forward_x11_timeout;
423 goto parse_time;
425 case oGatewayPorts:
426 intptr = &options->gateway_ports;
427 goto parse_flag;
429 case oExitOnForwardFailure:
430 intptr = &options->exit_on_forward_failure;
431 goto parse_flag;
433 case oUsePrivilegedPort:
434 intptr = &options->use_privileged_port;
435 goto parse_flag;
437 case oPasswordAuthentication:
438 intptr = &options->password_authentication;
439 goto parse_flag;
441 case oZeroKnowledgePasswordAuthentication:
442 intptr = &options->zero_knowledge_password_authentication;
443 goto parse_flag;
445 case oKbdInteractiveAuthentication:
446 intptr = &options->kbd_interactive_authentication;
447 goto parse_flag;
449 case oKbdInteractiveDevices:
450 charptr = &options->kbd_interactive_devices;
451 goto parse_string;
453 case oPubkeyAuthentication:
454 intptr = &options->pubkey_authentication;
455 goto parse_flag;
457 case oRSAAuthentication:
458 intptr = &options->rsa_authentication;
459 goto parse_flag;
461 case oRhostsRSAAuthentication:
462 intptr = &options->rhosts_rsa_authentication;
463 goto parse_flag;
465 case oHostbasedAuthentication:
466 intptr = &options->hostbased_authentication;
467 goto parse_flag;
469 case oChallengeResponseAuthentication:
470 intptr = &options->challenge_response_authentication;
471 goto parse_flag;
473 case oGssAuthentication:
474 intptr = &options->gss_authentication;
475 goto parse_flag;
477 case oGssDelegateCreds:
478 intptr = &options->gss_deleg_creds;
479 goto parse_flag;
481 case oBatchMode:
482 intptr = &options->batch_mode;
483 goto parse_flag;
485 case oCheckHostIP:
486 intptr = &options->check_host_ip;
487 goto parse_flag;
489 case oVerifyHostKeyDNS:
490 intptr = &options->verify_host_key_dns;
491 goto parse_yesnoask;
493 case oStrictHostKeyChecking:
494 intptr = &options->strict_host_key_checking;
495 parse_yesnoask:
496 arg = strdelim(&s);
497 if (!arg || *arg == '\0')
498 fatal("%.200s line %d: Missing yes/no/ask argument.",
499 filename, linenum);
500 value = 0; /* To avoid compiler warning... */
501 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
502 value = 1;
503 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
504 value = 0;
505 else if (strcmp(arg, "ask") == 0)
506 value = 2;
507 else
508 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
509 if (*activep && *intptr == -1)
510 *intptr = value;
511 break;
513 case oCompression:
514 intptr = &options->compression;
515 goto parse_flag;
517 case oTCPKeepAlive:
518 intptr = &options->tcp_keep_alive;
519 goto parse_flag;
521 case oNoHostAuthenticationForLocalhost:
522 intptr = &options->no_host_authentication_for_localhost;
523 goto parse_flag;
525 case oNumberOfPasswordPrompts:
526 intptr = &options->number_of_password_prompts;
527 goto parse_int;
529 case oCompressionLevel:
530 intptr = &options->compression_level;
531 goto parse_int;
533 case oRekeyLimit:
534 arg = strdelim(&s);
535 if (!arg || *arg == '\0')
536 fatal("%.200s line %d: Missing argument.", filename, linenum);
537 if (arg[0] < '0' || arg[0] > '9')
538 fatal("%.200s line %d: Bad number.", filename, linenum);
539 orig = val64 = strtoll(arg, &endofnumber, 10);
540 if (arg == endofnumber)
541 fatal("%.200s line %d: Bad number.", filename, linenum);
542 switch (toupper(*endofnumber)) {
543 case '\0':
544 scale = 1;
545 break;
546 case 'K':
547 scale = 1<<10;
548 break;
549 case 'M':
550 scale = 1<<20;
551 break;
552 case 'G':
553 scale = 1<<30;
554 break;
555 default:
556 fatal("%.200s line %d: Invalid RekeyLimit suffix",
557 filename, linenum);
559 val64 *= scale;
560 /* detect integer wrap and too-large limits */
561 if ((val64 / scale) != orig || val64 > UINT_MAX)
562 fatal("%.200s line %d: RekeyLimit too large",
563 filename, linenum);
564 if (val64 < 16)
565 fatal("%.200s line %d: RekeyLimit too small",
566 filename, linenum);
567 if (*activep && options->rekey_limit == -1)
568 options->rekey_limit = (u_int32_t)val64;
569 break;
571 case oIdentityFile:
572 arg = strdelim(&s);
573 if (!arg || *arg == '\0')
574 fatal("%.200s line %d: Missing argument.", filename, linenum);
575 if (*activep) {
576 intptr = &options->num_identity_files;
577 if (*intptr >= SSH_MAX_IDENTITY_FILES)
578 fatal("%.200s line %d: Too many identity files specified (max %d).",
579 filename, linenum, SSH_MAX_IDENTITY_FILES);
580 charptr = &options->identity_files[*intptr];
581 *charptr = xstrdup(arg);
582 *intptr = *intptr + 1;
584 break;
586 case oXAuthLocation:
587 charptr=&options->xauth_location;
588 goto parse_string;
590 case oUser:
591 charptr = &options->user;
592 parse_string:
593 arg = strdelim(&s);
594 if (!arg || *arg == '\0')
595 fatal("%.200s line %d: Missing argument.", filename, linenum);
596 if (*activep && *charptr == NULL)
597 *charptr = xstrdup(arg);
598 break;
600 case oGlobalKnownHostsFile:
601 charptr = &options->system_hostfile;
602 goto parse_string;
604 case oUserKnownHostsFile:
605 charptr = &options->user_hostfile;
606 goto parse_string;
608 case oGlobalKnownHostsFile2:
609 charptr = &options->system_hostfile2;
610 goto parse_string;
612 case oUserKnownHostsFile2:
613 charptr = &options->user_hostfile2;
614 goto parse_string;
616 case oHostName:
617 charptr = &options->hostname;
618 goto parse_string;
620 case oHostKeyAlias:
621 charptr = &options->host_key_alias;
622 goto parse_string;
624 case oPreferredAuthentications:
625 charptr = &options->preferred_authentications;
626 goto parse_string;
628 case oBindAddress:
629 charptr = &options->bind_address;
630 goto parse_string;
632 case oPKCS11Provider:
633 charptr = &options->pkcs11_provider;
634 goto parse_string;
636 case oProxyCommand:
637 charptr = &options->proxy_command;
638 parse_command:
639 if (s == NULL)
640 fatal("%.200s line %d: Missing argument.", filename, linenum);
641 len = strspn(s, WHITESPACE "=");
642 if (*activep && *charptr == NULL)
643 *charptr = xstrdup(s + len);
644 return 0;
646 case oPort:
647 intptr = &options->port;
648 parse_int:
649 arg = strdelim(&s);
650 if (!arg || *arg == '\0')
651 fatal("%.200s line %d: Missing argument.", filename, linenum);
652 if (arg[0] < '0' || arg[0] > '9')
653 fatal("%.200s line %d: Bad number.", filename, linenum);
655 /* Octal, decimal, or hex format? */
656 value = strtol(arg, &endofnumber, 0);
657 if (arg == endofnumber)
658 fatal("%.200s line %d: Bad number.", filename, linenum);
659 if (*activep && *intptr == -1)
660 *intptr = value;
661 break;
663 case oConnectionAttempts:
664 intptr = &options->connection_attempts;
665 goto parse_int;
667 case oCipher:
668 intptr = &options->cipher;
669 arg = strdelim(&s);
670 if (!arg || *arg == '\0')
671 fatal("%.200s line %d: Missing argument.", filename, linenum);
672 value = cipher_number(arg);
673 if (value == -1)
674 fatal("%.200s line %d: Bad cipher '%s'.",
675 filename, linenum, arg ? arg : "<NONE>");
676 if (*activep && *intptr == -1)
677 *intptr = value;
678 break;
680 case oCiphers:
681 arg = strdelim(&s);
682 if (!arg || *arg == '\0')
683 fatal("%.200s line %d: Missing argument.", filename, linenum);
684 if (!ciphers_valid(arg))
685 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
686 filename, linenum, arg ? arg : "<NONE>");
687 if (*activep && options->ciphers == NULL)
688 options->ciphers = xstrdup(arg);
689 break;
691 case oMacs:
692 arg = strdelim(&s);
693 if (!arg || *arg == '\0')
694 fatal("%.200s line %d: Missing argument.", filename, linenum);
695 if (!mac_valid(arg))
696 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
697 filename, linenum, arg ? arg : "<NONE>");
698 if (*activep && options->macs == NULL)
699 options->macs = xstrdup(arg);
700 break;
702 case oHostKeyAlgorithms:
703 arg = strdelim(&s);
704 if (!arg || *arg == '\0')
705 fatal("%.200s line %d: Missing argument.", filename, linenum);
706 if (!key_names_valid2(arg))
707 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
708 filename, linenum, arg ? arg : "<NONE>");
709 if (*activep && options->hostkeyalgorithms == NULL)
710 options->hostkeyalgorithms = xstrdup(arg);
711 break;
713 case oProtocol:
714 intptr = &options->protocol;
715 arg = strdelim(&s);
716 if (!arg || *arg == '\0')
717 fatal("%.200s line %d: Missing argument.", filename, linenum);
718 value = proto_spec(arg);
719 if (value == SSH_PROTO_UNKNOWN)
720 fatal("%.200s line %d: Bad protocol spec '%s'.",
721 filename, linenum, arg ? arg : "<NONE>");
722 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
723 *intptr = value;
724 break;
726 case oLogLevel:
727 log_level_ptr = &options->log_level;
728 arg = strdelim(&s);
729 value = log_level_number(arg);
730 if (value == SYSLOG_LEVEL_NOT_SET)
731 fatal("%.200s line %d: unsupported log level '%s'",
732 filename, linenum, arg ? arg : "<NONE>");
733 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
734 *log_level_ptr = (LogLevel) value;
735 break;
737 case oLocalForward:
738 case oRemoteForward:
739 case oDynamicForward:
740 arg = strdelim(&s);
741 if (arg == NULL || *arg == '\0')
742 fatal("%.200s line %d: Missing port argument.",
743 filename, linenum);
745 if (opcode == oLocalForward ||
746 opcode == oRemoteForward) {
747 arg2 = strdelim(&s);
748 if (arg2 == NULL || *arg2 == '\0')
749 fatal("%.200s line %d: Missing target argument.",
750 filename, linenum);
752 /* construct a string for parse_forward */
753 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
754 } else if (opcode == oDynamicForward) {
755 strlcpy(fwdarg, arg, sizeof(fwdarg));
758 if (parse_forward(&fwd, fwdarg,
759 opcode == oDynamicForward ? 1 : 0,
760 opcode == oRemoteForward ? 1 : 0) == 0)
761 fatal("%.200s line %d: Bad forwarding specification.",
762 filename, linenum);
764 if (*activep) {
765 if (opcode == oLocalForward ||
766 opcode == oDynamicForward)
767 add_local_forward(options, &fwd);
768 else if (opcode == oRemoteForward)
769 add_remote_forward(options, &fwd);
771 break;
773 case oClearAllForwardings:
774 intptr = &options->clear_forwardings;
775 goto parse_flag;
777 case oHost:
778 *activep = 0;
779 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
780 if (match_pattern(host, arg)) {
781 debug("Applying options for %.100s", arg);
782 *activep = 1;
783 break;
785 /* Avoid garbage check below, as strdelim is done. */
786 return 0;
788 case oEscapeChar:
789 intptr = &options->escape_char;
790 arg = strdelim(&s);
791 if (!arg || *arg == '\0')
792 fatal("%.200s line %d: Missing argument.", filename, linenum);
793 if (arg[0] == '^' && arg[2] == 0 &&
794 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
795 value = (u_char) arg[1] & 31;
796 else if (strlen(arg) == 1)
797 value = (u_char) arg[0];
798 else if (strcmp(arg, "none") == 0)
799 value = SSH_ESCAPECHAR_NONE;
800 else {
801 fatal("%.200s line %d: Bad escape character.",
802 filename, linenum);
803 /* NOTREACHED */
804 value = 0; /* Avoid compiler warning. */
806 if (*activep && *intptr == -1)
807 *intptr = value;
808 break;
810 case oAddressFamily:
811 arg = strdelim(&s);
812 if (!arg || *arg == '\0')
813 fatal("%s line %d: missing address family.",
814 filename, linenum);
815 intptr = &options->address_family;
816 if (strcasecmp(arg, "inet") == 0)
817 value = AF_INET;
818 else if (strcasecmp(arg, "inet6") == 0)
819 value = AF_INET6;
820 else if (strcasecmp(arg, "any") == 0)
821 value = AF_UNSPEC;
822 else
823 fatal("Unsupported AddressFamily \"%s\"", arg);
824 if (*activep && *intptr == -1)
825 *intptr = value;
826 break;
828 case oEnableSSHKeysign:
829 intptr = &options->enable_ssh_keysign;
830 goto parse_flag;
832 case oIdentitiesOnly:
833 intptr = &options->identities_only;
834 goto parse_flag;
836 case oServerAliveInterval:
837 intptr = &options->server_alive_interval;
838 goto parse_time;
840 case oServerAliveCountMax:
841 intptr = &options->server_alive_count_max;
842 goto parse_int;
844 case oSendEnv:
845 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
846 if (strchr(arg, '=') != NULL)
847 fatal("%s line %d: Invalid environment name.",
848 filename, linenum);
849 if (!*activep)
850 continue;
851 if (options->num_send_env >= MAX_SEND_ENV)
852 fatal("%s line %d: too many send env.",
853 filename, linenum);
854 options->send_env[options->num_send_env++] =
855 xstrdup(arg);
857 break;
859 case oControlPath:
860 charptr = &options->control_path;
861 goto parse_string;
863 case oControlMaster:
864 intptr = &options->control_master;
865 arg = strdelim(&s);
866 if (!arg || *arg == '\0')
867 fatal("%.200s line %d: Missing ControlMaster argument.",
868 filename, linenum);
869 value = 0; /* To avoid compiler warning... */
870 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
871 value = SSHCTL_MASTER_YES;
872 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
873 value = SSHCTL_MASTER_NO;
874 else if (strcmp(arg, "auto") == 0)
875 value = SSHCTL_MASTER_AUTO;
876 else if (strcmp(arg, "ask") == 0)
877 value = SSHCTL_MASTER_ASK;
878 else if (strcmp(arg, "autoask") == 0)
879 value = SSHCTL_MASTER_AUTO_ASK;
880 else
881 fatal("%.200s line %d: Bad ControlMaster argument.",
882 filename, linenum);
883 if (*activep && *intptr == -1)
884 *intptr = value;
885 break;
887 case oControlPersist:
888 /* no/false/yes/true, or a time spec */
889 intptr = &options->control_persist;
890 arg = strdelim(&s);
891 if (!arg || *arg == '\0')
892 fatal("%.200s line %d: Missing ControlPersist"
893 " argument.", filename, linenum);
894 value = 0;
895 value2 = 0; /* timeout */
896 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
897 value = 0;
898 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
899 value = 1;
900 else if ((value2 = convtime(arg)) >= 0)
901 value = 1;
902 else
903 fatal("%.200s line %d: Bad ControlPersist argument.",
904 filename, linenum);
905 if (*activep && *intptr == -1) {
906 *intptr = value;
907 options->control_persist_timeout = value2;
909 break;
911 case oHashKnownHosts:
912 intptr = &options->hash_known_hosts;
913 goto parse_flag;
915 case oTunnel:
916 intptr = &options->tun_open;
917 arg = strdelim(&s);
918 if (!arg || *arg == '\0')
919 fatal("%s line %d: Missing yes/point-to-point/"
920 "ethernet/no argument.", filename, linenum);
921 value = 0; /* silence compiler */
922 if (strcasecmp(arg, "ethernet") == 0)
923 value = SSH_TUNMODE_ETHERNET;
924 else if (strcasecmp(arg, "point-to-point") == 0)
925 value = SSH_TUNMODE_POINTOPOINT;
926 else if (strcasecmp(arg, "yes") == 0)
927 value = SSH_TUNMODE_DEFAULT;
928 else if (strcasecmp(arg, "no") == 0)
929 value = SSH_TUNMODE_NO;
930 else
931 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
932 "no argument: %s", filename, linenum, arg);
933 if (*activep)
934 *intptr = value;
935 break;
937 case oTunnelDevice:
938 arg = strdelim(&s);
939 if (!arg || *arg == '\0')
940 fatal("%.200s line %d: Missing argument.", filename, linenum);
941 value = a2tun(arg, &value2);
942 if (value == SSH_TUNID_ERR)
943 fatal("%.200s line %d: Bad tun device.", filename, linenum);
944 if (*activep) {
945 options->tun_local = value;
946 options->tun_remote = value2;
948 break;
950 case oLocalCommand:
951 charptr = &options->local_command;
952 goto parse_command;
954 case oPermitLocalCommand:
955 intptr = &options->permit_local_command;
956 goto parse_flag;
958 case oVisualHostKey:
959 intptr = &options->visual_host_key;
960 goto parse_flag;
962 case oUseRoaming:
963 intptr = &options->use_roaming;
964 goto parse_flag;
966 case oDeprecated:
967 debug("%s line %d: Deprecated option \"%s\"",
968 filename, linenum, keyword);
969 return 0;
971 case oUnsupported:
972 error("%s line %d: Unsupported option \"%s\"",
973 filename, linenum, keyword);
974 return 0;
976 default:
977 fatal("process_config_line: Unimplemented opcode %d", opcode);
980 /* Check that there is no garbage at end of line. */
981 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
982 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
983 filename, linenum, arg);
985 return 0;
990 * Reads the config file and modifies the options accordingly. Options
991 * should already be initialized before this call. This never returns if
992 * there is an error. If the file does not exist, this returns 0.
996 read_config_file(const char *filename, const char *host, Options *options,
997 int checkperm)
999 FILE *f;
1000 char line[1024];
1001 int active, linenum;
1002 int bad_options = 0;
1004 if ((f = fopen(filename, "r")) == NULL)
1005 return 0;
1007 if (checkperm) {
1008 struct stat sb;
1010 if (fstat(fileno(f), &sb) == -1)
1011 fatal("fstat %s: %s", filename, strerror(errno));
1012 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1013 (sb.st_mode & 022) != 0))
1014 fatal("Bad owner or permissions on %s", filename);
1017 debug("Reading configuration data %.200s", filename);
1020 * Mark that we are now processing the options. This flag is turned
1021 * on/off by Host specifications.
1023 active = 1;
1024 linenum = 0;
1025 while (fgets(line, sizeof(line), f)) {
1026 /* Update line number counter. */
1027 linenum++;
1028 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
1029 bad_options++;
1031 fclose(f);
1032 if (bad_options > 0)
1033 fatal("%s: terminating, %d bad configuration options",
1034 filename, bad_options);
1035 return 1;
1039 * Initializes options to special values that indicate that they have not yet
1040 * been set. Read_config_file will only set options with this value. Options
1041 * are processed in the following order: command line, user config file,
1042 * system config file. Last, fill_default_options is called.
1045 void
1046 initialize_options(Options * options)
1048 memset(options, 'X', sizeof(*options));
1049 options->forward_agent = -1;
1050 options->forward_x11 = -1;
1051 options->forward_x11_trusted = -1;
1052 options->forward_x11_timeout = -1;
1053 options->exit_on_forward_failure = -1;
1054 options->xauth_location = NULL;
1055 options->gateway_ports = -1;
1056 options->use_privileged_port = -1;
1057 options->rsa_authentication = -1;
1058 options->pubkey_authentication = -1;
1059 options->challenge_response_authentication = -1;
1060 options->gss_authentication = -1;
1061 options->gss_deleg_creds = -1;
1062 options->password_authentication = -1;
1063 options->kbd_interactive_authentication = -1;
1064 options->kbd_interactive_devices = NULL;
1065 options->rhosts_rsa_authentication = -1;
1066 options->hostbased_authentication = -1;
1067 options->batch_mode = -1;
1068 options->check_host_ip = -1;
1069 options->strict_host_key_checking = -1;
1070 options->compression = -1;
1071 options->tcp_keep_alive = -1;
1072 options->compression_level = -1;
1073 options->port = -1;
1074 options->address_family = -1;
1075 options->connection_attempts = -1;
1076 options->connection_timeout = -1;
1077 options->number_of_password_prompts = -1;
1078 options->cipher = -1;
1079 options->ciphers = NULL;
1080 options->macs = NULL;
1081 options->hostkeyalgorithms = NULL;
1082 options->protocol = SSH_PROTO_UNKNOWN;
1083 options->num_identity_files = 0;
1084 options->hostname = NULL;
1085 options->host_key_alias = NULL;
1086 options->proxy_command = NULL;
1087 options->user = NULL;
1088 options->escape_char = -1;
1089 options->system_hostfile = NULL;
1090 options->user_hostfile = NULL;
1091 options->system_hostfile2 = NULL;
1092 options->user_hostfile2 = NULL;
1093 options->local_forwards = NULL;
1094 options->num_local_forwards = 0;
1095 options->remote_forwards = NULL;
1096 options->num_remote_forwards = 0;
1097 options->clear_forwardings = -1;
1098 options->log_level = SYSLOG_LEVEL_NOT_SET;
1099 options->preferred_authentications = NULL;
1100 options->bind_address = NULL;
1101 options->pkcs11_provider = NULL;
1102 options->enable_ssh_keysign = - 1;
1103 options->no_host_authentication_for_localhost = - 1;
1104 options->identities_only = - 1;
1105 options->rekey_limit = - 1;
1106 options->verify_host_key_dns = -1;
1107 options->server_alive_interval = -1;
1108 options->server_alive_count_max = -1;
1109 options->num_send_env = 0;
1110 options->control_path = NULL;
1111 options->control_master = -1;
1112 options->control_persist = -1;
1113 options->control_persist_timeout = 0;
1114 options->hash_known_hosts = -1;
1115 options->tun_open = -1;
1116 options->tun_local = -1;
1117 options->tun_remote = -1;
1118 options->local_command = NULL;
1119 options->permit_local_command = -1;
1120 options->use_roaming = -1;
1121 options->visual_host_key = -1;
1122 options->zero_knowledge_password_authentication = -1;
1126 * Called after processing other sources of option data, this fills those
1127 * options for which no value has been specified with their default values.
1130 void
1131 fill_default_options(Options * options)
1133 int len;
1135 if (options->forward_agent == -1)
1136 options->forward_agent = 0;
1137 if (options->forward_x11 == -1)
1138 options->forward_x11 = 0;
1139 if (options->forward_x11_trusted == -1)
1140 options->forward_x11_trusted = 0;
1141 if (options->forward_x11_timeout == -1)
1142 options->forward_x11_timeout = 1200;
1143 if (options->exit_on_forward_failure == -1)
1144 options->exit_on_forward_failure = 0;
1145 if (options->xauth_location == NULL)
1146 options->xauth_location = _PATH_XAUTH;
1147 if (options->gateway_ports == -1)
1148 options->gateway_ports = 0;
1149 if (options->use_privileged_port == -1)
1150 options->use_privileged_port = 0;
1151 if (options->rsa_authentication == -1)
1152 options->rsa_authentication = 1;
1153 if (options->pubkey_authentication == -1)
1154 options->pubkey_authentication = 1;
1155 if (options->challenge_response_authentication == -1)
1156 options->challenge_response_authentication = 1;
1157 if (options->gss_authentication == -1)
1158 options->gss_authentication = 0;
1159 if (options->gss_deleg_creds == -1)
1160 options->gss_deleg_creds = 0;
1161 if (options->password_authentication == -1)
1162 options->password_authentication = 1;
1163 if (options->kbd_interactive_authentication == -1)
1164 options->kbd_interactive_authentication = 1;
1165 if (options->rhosts_rsa_authentication == -1)
1166 options->rhosts_rsa_authentication = 0;
1167 if (options->hostbased_authentication == -1)
1168 options->hostbased_authentication = 0;
1169 if (options->batch_mode == -1)
1170 options->batch_mode = 0;
1171 if (options->check_host_ip == -1)
1172 options->check_host_ip = 1;
1173 if (options->strict_host_key_checking == -1)
1174 options->strict_host_key_checking = 2; /* 2 is default */
1175 if (options->compression == -1)
1176 options->compression = 0;
1177 if (options->tcp_keep_alive == -1)
1178 options->tcp_keep_alive = 1;
1179 if (options->compression_level == -1)
1180 options->compression_level = 6;
1181 if (options->port == -1)
1182 options->port = 0; /* Filled in ssh_connect. */
1183 if (options->address_family == -1)
1184 options->address_family = AF_UNSPEC;
1185 if (options->connection_attempts == -1)
1186 options->connection_attempts = 1;
1187 if (options->number_of_password_prompts == -1)
1188 options->number_of_password_prompts = 3;
1189 /* Selected in ssh_login(). */
1190 if (options->cipher == -1)
1191 options->cipher = SSH_CIPHER_NOT_SET;
1192 /* options->ciphers, default set in myproposals.h */
1193 /* options->macs, default set in myproposals.h */
1194 /* options->hostkeyalgorithms, default set in myproposals.h */
1195 if (options->protocol == SSH_PROTO_UNKNOWN)
1196 options->protocol = SSH_PROTO_2;
1197 if (options->num_identity_files == 0) {
1198 if (options->protocol & SSH_PROTO_1) {
1199 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1200 options->identity_files[options->num_identity_files] =
1201 xmalloc(len);
1202 snprintf(options->identity_files[options->num_identity_files++],
1203 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1205 if (options->protocol & SSH_PROTO_2) {
1206 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1207 options->identity_files[options->num_identity_files] =
1208 xmalloc(len);
1209 snprintf(options->identity_files[options->num_identity_files++],
1210 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1212 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1213 options->identity_files[options->num_identity_files] =
1214 xmalloc(len);
1215 snprintf(options->identity_files[options->num_identity_files++],
1216 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1218 len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1;
1219 options->identity_files[options->num_identity_files] =
1220 xmalloc(len);
1221 snprintf(options->identity_files[options->num_identity_files++],
1222 len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA);
1225 if (options->escape_char == -1)
1226 options->escape_char = '~';
1227 if (options->system_hostfile == NULL)
1228 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1229 if (options->user_hostfile == NULL)
1230 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1231 if (options->system_hostfile2 == NULL)
1232 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1233 if (options->user_hostfile2 == NULL)
1234 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1235 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1236 options->log_level = SYSLOG_LEVEL_INFO;
1237 if (options->clear_forwardings == 1)
1238 clear_forwardings(options);
1239 if (options->no_host_authentication_for_localhost == - 1)
1240 options->no_host_authentication_for_localhost = 0;
1241 if (options->identities_only == -1)
1242 options->identities_only = 0;
1243 if (options->enable_ssh_keysign == -1)
1244 options->enable_ssh_keysign = 0;
1245 if (options->rekey_limit == -1)
1246 options->rekey_limit = 0;
1247 if (options->verify_host_key_dns == -1)
1248 options->verify_host_key_dns = 0;
1249 if (options->server_alive_interval == -1)
1250 options->server_alive_interval = 0;
1251 if (options->server_alive_count_max == -1)
1252 options->server_alive_count_max = 3;
1253 if (options->control_master == -1)
1254 options->control_master = 0;
1255 if (options->control_persist == -1) {
1256 options->control_persist = 0;
1257 options->control_persist_timeout = 0;
1259 if (options->hash_known_hosts == -1)
1260 options->hash_known_hosts = 0;
1261 if (options->tun_open == -1)
1262 options->tun_open = SSH_TUNMODE_NO;
1263 if (options->tun_local == -1)
1264 options->tun_local = SSH_TUNID_ANY;
1265 if (options->tun_remote == -1)
1266 options->tun_remote = SSH_TUNID_ANY;
1267 if (options->permit_local_command == -1)
1268 options->permit_local_command = 0;
1269 if (options->use_roaming == -1)
1270 options->use_roaming = 1;
1271 if (options->visual_host_key == -1)
1272 options->visual_host_key = 0;
1273 if (options->zero_knowledge_password_authentication == -1)
1274 options->zero_knowledge_password_authentication = 0;
1275 /* options->local_command should not be set by default */
1276 /* options->proxy_command should not be set by default */
1277 /* options->user will be set in the main program if appropriate */
1278 /* options->hostname will be set in the main program if appropriate */
1279 /* options->host_key_alias should not be set by default */
1280 /* options->preferred_authentications will be set in ssh */
1284 * parse_forward
1285 * parses a string containing a port forwarding specification of the form:
1286 * dynamicfwd == 0
1287 * [listenhost:]listenport:connecthost:connectport
1288 * dynamicfwd == 1
1289 * [listenhost:]listenport
1290 * returns number of arguments parsed or zero on error
1293 parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1295 int i;
1296 char *p, *cp, *fwdarg[4];
1298 memset(fwd, '\0', sizeof(*fwd));
1300 cp = p = xstrdup(fwdspec);
1302 /* skip leading spaces */
1303 while (isspace(*cp))
1304 cp++;
1306 for (i = 0; i < 4; ++i)
1307 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1308 break;
1310 /* Check for trailing garbage */
1311 if (cp != NULL)
1312 i = 0; /* failure */
1314 switch (i) {
1315 case 1:
1316 fwd->listen_host = NULL;
1317 fwd->listen_port = a2port(fwdarg[0]);
1318 fwd->connect_host = xstrdup("socks");
1319 break;
1321 case 2:
1322 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1323 fwd->listen_port = a2port(fwdarg[1]);
1324 fwd->connect_host = xstrdup("socks");
1325 break;
1327 case 3:
1328 fwd->listen_host = NULL;
1329 fwd->listen_port = a2port(fwdarg[0]);
1330 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1331 fwd->connect_port = a2port(fwdarg[2]);
1332 break;
1334 case 4:
1335 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1336 fwd->listen_port = a2port(fwdarg[1]);
1337 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1338 fwd->connect_port = a2port(fwdarg[3]);
1339 break;
1340 default:
1341 i = 0; /* failure */
1344 xfree(p);
1346 if (dynamicfwd) {
1347 if (!(i == 1 || i == 2))
1348 goto fail_free;
1349 } else {
1350 if (!(i == 3 || i == 4))
1351 goto fail_free;
1352 if (fwd->connect_port <= 0)
1353 goto fail_free;
1356 if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1357 goto fail_free;
1359 if (fwd->connect_host != NULL &&
1360 strlen(fwd->connect_host) >= NI_MAXHOST)
1361 goto fail_free;
1362 if (fwd->listen_host != NULL &&
1363 strlen(fwd->listen_host) >= NI_MAXHOST)
1364 goto fail_free;
1367 return (i);
1369 fail_free:
1370 if (fwd->connect_host != NULL) {
1371 xfree(fwd->connect_host);
1372 fwd->connect_host = NULL;
1374 if (fwd->listen_host != NULL) {
1375 xfree(fwd->listen_host);
1376 fwd->listen_host = NULL;
1378 return (0);