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