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