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