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