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