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