]> andersk Git - gssapi-openssh.git/blob - openssh/readconf.c
http://www.psc.edu/networking/projects/hpn-ssh/openssh-5.2p1-hpn13v6.diff.gz committe...
[gssapi-openssh.git] / openssh / readconf.c
1 /* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */
2 /*
3  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *                    All rights reserved
6  * Functions for reading the configuration files.
7  *
8  * As far as I am concerned, the code I have written for this software
9  * can be used freely for any purpose.  Any derived versions of this
10  * software must be clearly marked as such, and if the derived work is
11  * incompatible with the protocol description in the RFC file, it must be
12  * called by a name other than "ssh" or "Secure Shell".
13  */
14
15 #include "includes.h"
16
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/socket.h>
20
21 #include <netinet/in.h>
22
23 #include <ctype.h>
24 #include <errno.h>
25 #include <netdb.h>
26 #include <signal.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31
32 #include "xmalloc.h"
33 #include "ssh.h"
34 #include "compat.h"
35 #include "cipher.h"
36 #include "pathnames.h"
37 #include "log.h"
38 #include "key.h"
39 #include "readconf.h"
40 #include "match.h"
41 #include "misc.h"
42 #include "buffer.h"
43 #include "kex.h"
44 #include "mac.h"
45
46 /* Format of the configuration file:
47
48    # Configuration data is parsed as follows:
49    #  1. command line options
50    #  2. user-specific file
51    #  3. system-wide file
52    # Any configuration value is only changed the first time it is set.
53    # Thus, host-specific definitions should be at the beginning of the
54    # configuration file, and defaults at the end.
55
56    # Host-specific declarations.  These may override anything above.  A single
57    # host may match multiple declarations; these are processed in the order
58    # that they are given in.
59
60    Host *.ngs.fi ngs.fi
61      User foo
62
63    Host fake.com
64      HostName another.host.name.real.org
65      User blaah
66      Port 34289
67      ForwardX11 no
68      ForwardAgent no
69
70    Host books.com
71      RemoteForward 9999 shadows.cs.hut.fi:9999
72      Cipher 3des
73
74    Host fascist.blob.com
75      Port 23123
76      User tylonen
77      PasswordAuthentication no
78
79    Host puukko.hut.fi
80      User t35124p
81      ProxyCommand ssh-proxy %h %p
82
83    Host *.fr
84      PublicKeyAuthentication no
85
86    Host *.su
87      Cipher none
88      PasswordAuthentication no
89
90    Host vpn.fake.com
91      Tunnel yes
92      TunnelDevice 3
93
94    # Defaults for various options
95    Host *
96      ForwardAgent no
97      ForwardX11 no
98      PasswordAuthentication yes
99      RSAAuthentication yes
100      RhostsRSAAuthentication yes
101      StrictHostKeyChecking yes
102      TcpKeepAlive no
103      IdentityFile ~/.ssh/identity
104      Port 22
105      EscapeChar ~
106
107 */
108
109 /* Keyword tokens. */
110
111 typedef enum {
112         oBadOption,
113         oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
114         oExitOnForwardFailure,
115         oPasswordAuthentication, oRSAAuthentication,
116         oChallengeResponseAuthentication, oXAuthLocation,
117         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
118         oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
119         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
120         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
121         oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
122         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
123         oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
124         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
125         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
126         oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
127         oClearAllForwardings, oNoHostAuthenticationForLocalhost,
128         oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
129         oAddressFamily, oGssAuthentication, oGssDelegateCreds,
130         oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
131         oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
132         oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
133         oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
134         oVisualHostKey, oZeroKnowledgePasswordAuthentication,
135         oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
136         oHPNBufferSize,
137         oDeprecated, oUnsupported
138 } OpCodes;
139
140 /* Textual representations of the tokens. */
141
142 static struct {
143         const char *name;
144         OpCodes opcode;
145 } keywords[] = {
146         { "forwardagent", oForwardAgent },
147         { "forwardx11", oForwardX11 },
148         { "forwardx11trusted", oForwardX11Trusted },
149         { "exitonforwardfailure", oExitOnForwardFailure },
150         { "xauthlocation", oXAuthLocation },
151         { "gatewayports", oGatewayPorts },
152         { "useprivilegedport", oUsePrivilegedPort },
153         { "rhostsauthentication", oDeprecated },
154         { "passwordauthentication", oPasswordAuthentication },
155         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
156         { "kbdinteractivedevices", oKbdInteractiveDevices },
157         { "rsaauthentication", oRSAAuthentication },
158         { "pubkeyauthentication", oPubkeyAuthentication },
159         { "dsaauthentication", oPubkeyAuthentication },             /* alias */
160         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
161         { "hostbasedauthentication", oHostbasedAuthentication },
162         { "challengeresponseauthentication", oChallengeResponseAuthentication },
163         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
164         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
165         { "kerberosauthentication", oUnsupported },
166         { "kerberostgtpassing", oUnsupported },
167         { "afstokenpassing", oUnsupported },
168 #if defined(GSSAPI)
169         { "gssapiauthentication", oGssAuthentication },
170         { "gssapikeyexchange", oGssKeyEx },
171         { "gssapidelegatecredentials", oGssDelegateCreds },
172         { "gssapitrustdns", oGssTrustDns },
173         { "gssapiclientidentity", oGssClientIdentity },
174         { "gssapirenewalforcesrekey", oGssRenewalRekey },
175 #else
176         { "gssapiauthentication", oUnsupported },
177         { "gssapikeyexchange", oUnsupported },
178         { "gssapidelegatecredentials", oUnsupported },
179         { "gssapitrustdns", oUnsupported },
180         { "gssapiclientidentity", oUnsupported },
181         { "gssapirenewalforcesrekey", oUnsupported },
182 #endif
183         { "fallbacktorsh", oDeprecated },
184         { "usersh", oDeprecated },
185         { "identityfile", oIdentityFile },
186         { "identityfile2", oIdentityFile },                     /* obsolete */
187         { "identitiesonly", oIdentitiesOnly },
188         { "hostname", oHostName },
189         { "hostkeyalias", oHostKeyAlias },
190         { "proxycommand", oProxyCommand },
191         { "port", oPort },
192         { "cipher", oCipher },
193         { "ciphers", oCiphers },
194         { "macs", oMacs },
195         { "protocol", oProtocol },
196         { "remoteforward", oRemoteForward },
197         { "localforward", oLocalForward },
198         { "user", oUser },
199         { "host", oHost },
200         { "escapechar", oEscapeChar },
201         { "globalknownhostsfile", oGlobalKnownHostsFile },
202         { "globalknownhostsfile2", oGlobalKnownHostsFile2 },    /* obsolete */
203         { "userknownhostsfile", oUserKnownHostsFile },
204         { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
205         { "connectionattempts", oConnectionAttempts },
206         { "batchmode", oBatchMode },
207         { "checkhostip", oCheckHostIP },
208         { "stricthostkeychecking", oStrictHostKeyChecking },
209         { "compression", oCompression },
210         { "compressionlevel", oCompressionLevel },
211         { "tcpkeepalive", oTCPKeepAlive },
212         { "keepalive", oTCPKeepAlive },                         /* obsolete */
213         { "numberofpasswordprompts", oNumberOfPasswordPrompts },
214         { "loglevel", oLogLevel },
215         { "dynamicforward", oDynamicForward },
216         { "preferredauthentications", oPreferredAuthentications },
217         { "hostkeyalgorithms", oHostKeyAlgorithms },
218         { "bindaddress", oBindAddress },
219 #ifdef SMARTCARD
220         { "smartcarddevice", oSmartcardDevice },
221 #else
222         { "smartcarddevice", oUnsupported },
223 #endif
224         { "clearallforwardings", oClearAllForwardings },
225         { "enablesshkeysign", oEnableSSHKeysign },
226         { "verifyhostkeydns", oVerifyHostKeyDNS },
227         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
228         { "rekeylimit", oRekeyLimit },
229         { "connecttimeout", oConnectTimeout },
230         { "addressfamily", oAddressFamily },
231         { "serveraliveinterval", oServerAliveInterval },
232         { "serveralivecountmax", oServerAliveCountMax },
233         { "sendenv", oSendEnv },
234         { "controlpath", oControlPath },
235         { "controlmaster", oControlMaster },
236         { "hashknownhosts", oHashKnownHosts },
237         { "tunnel", oTunnel },
238         { "tunneldevice", oTunnelDevice },
239         { "localcommand", oLocalCommand },
240         { "permitlocalcommand", oPermitLocalCommand },
241         { "visualhostkey", oVisualHostKey },
242 #ifdef JPAKE
243         { "zeroknowledgepasswordauthentication",
244             oZeroKnowledgePasswordAuthentication },
245 #else
246         { "zeroknowledgepasswordauthentication", oUnsupported },
247 #endif
248         { "noneenabled", oNoneEnabled },
249         { "tcprcvbufpoll", oTcpRcvBufPoll },
250         { "tcprcvbuf", oTcpRcvBuf },
251         { "noneswitch", oNoneSwitch },
252         { "hpndisabled", oHPNDisabled },
253         { "hpnbuffersize", oHPNBufferSize },
254
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 oDeprecated:
986                 debug("%s line %d: Deprecated option \"%s\"",
987                     filename, linenum, keyword);
988                 return 0;
989
990         case oUnsupported:
991                 error("%s line %d: Unsupported option \"%s\"",
992                     filename, linenum, keyword);
993                 return 0;
994
995         default:
996                 fatal("process_config_line: Unimplemented opcode %d", opcode);
997         }
998
999         /* Check that there is no garbage at end of line. */
1000         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1001                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1002                     filename, linenum, arg);
1003         }
1004         return 0;
1005 }
1006
1007
1008 /*
1009  * Reads the config file and modifies the options accordingly.  Options
1010  * should already be initialized before this call.  This never returns if
1011  * there is an error.  If the file does not exist, this returns 0.
1012  */
1013
1014 int
1015 read_config_file(const char *filename, const char *host, Options *options,
1016     int checkperm)
1017 {
1018         FILE *f;
1019         char line[1024];
1020         int active, linenum;
1021         int bad_options = 0;
1022
1023         if ((f = fopen(filename, "r")) == NULL)
1024                 return 0;
1025
1026         if (checkperm) {
1027                 struct stat sb;
1028
1029                 if (fstat(fileno(f), &sb) == -1)
1030                         fatal("fstat %s: %s", filename, strerror(errno));
1031                 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1032                     (sb.st_mode & 022) != 0))
1033                         fatal("Bad owner or permissions on %s", filename);
1034         }
1035
1036         debug("Reading configuration data %.200s", filename);
1037
1038         /*
1039          * Mark that we are now processing the options.  This flag is turned
1040          * on/off by Host specifications.
1041          */
1042         active = 1;
1043         linenum = 0;
1044         while (fgets(line, sizeof(line), f)) {
1045                 /* Update line number counter. */
1046                 linenum++;
1047                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
1048                         bad_options++;
1049         }
1050         fclose(f);
1051         if (bad_options > 0)
1052                 fatal("%s: terminating, %d bad configuration options",
1053                     filename, bad_options);
1054         return 1;
1055 }
1056
1057 /*
1058  * Initializes options to special values that indicate that they have not yet
1059  * been set.  Read_config_file will only set options with this value. Options
1060  * are processed in the following order: command line, user config file,
1061  * system config file.  Last, fill_default_options is called.
1062  */
1063
1064 void
1065 initialize_options(Options * options)
1066 {
1067         memset(options, 'X', sizeof(*options));
1068         options->forward_agent = -1;
1069         options->forward_x11 = -1;
1070         options->forward_x11_trusted = -1;
1071         options->exit_on_forward_failure = -1;
1072         options->xauth_location = NULL;
1073         options->gateway_ports = -1;
1074         options->use_privileged_port = -1;
1075         options->rsa_authentication = -1;
1076         options->pubkey_authentication = -1;
1077         options->challenge_response_authentication = -1;
1078         options->gss_authentication = -1;
1079         options->gss_keyex = -1;
1080         options->gss_deleg_creds = -1;
1081         options->gss_trust_dns = -1;
1082         options->gss_renewal_rekey = -1;
1083         options->gss_client_identity = NULL;
1084         options->password_authentication = -1;
1085         options->kbd_interactive_authentication = -1;
1086         options->kbd_interactive_devices = NULL;
1087         options->rhosts_rsa_authentication = -1;
1088         options->hostbased_authentication = -1;
1089         options->batch_mode = -1;
1090         options->check_host_ip = -1;
1091         options->strict_host_key_checking = -1;
1092         options->compression = -1;
1093         options->tcp_keep_alive = -1;
1094         options->compression_level = -1;
1095         options->port = -1;
1096         options->address_family = -1;
1097         options->connection_attempts = -1;
1098         options->connection_timeout = -1;
1099         options->number_of_password_prompts = -1;
1100         options->cipher = -1;
1101         options->ciphers = NULL;
1102         options->macs = NULL;
1103         options->hostkeyalgorithms = NULL;
1104         options->protocol = SSH_PROTO_UNKNOWN;
1105         options->num_identity_files = 0;
1106         options->hostname = NULL;
1107         options->host_key_alias = NULL;
1108         options->proxy_command = NULL;
1109         options->user = NULL;
1110         options->escape_char = -1;
1111         options->system_hostfile = NULL;
1112         options->user_hostfile = NULL;
1113         options->system_hostfile2 = NULL;
1114         options->user_hostfile2 = NULL;
1115         options->num_local_forwards = 0;
1116         options->num_remote_forwards = 0;
1117         options->clear_forwardings = -1;
1118         options->log_level = SYSLOG_LEVEL_NOT_SET;
1119         options->preferred_authentications = NULL;
1120         options->bind_address = NULL;
1121         options->smartcard_device = NULL;
1122         options->enable_ssh_keysign = - 1;
1123         options->no_host_authentication_for_localhost = - 1;
1124         options->identities_only = - 1;
1125         options->rekey_limit = - 1;
1126         options->verify_host_key_dns = -1;
1127         options->server_alive_interval = -1;
1128         options->server_alive_count_max = -1;
1129         options->num_send_env = 0;
1130         options->control_path = NULL;
1131         options->control_master = -1;
1132         options->hash_known_hosts = -1;
1133         options->tun_open = -1;
1134         options->tun_local = -1;
1135         options->tun_remote = -1;
1136         options->local_command = NULL;
1137         options->permit_local_command = -1;
1138         options->visual_host_key = -1;
1139         options->zero_knowledge_password_authentication = -1;
1140         options->none_switch = -1;
1141         options->none_enabled = -1;
1142         options->hpn_disabled = -1;
1143         options->hpn_buffer_size = -1;
1144         options->tcp_rcv_buf_poll = -1;
1145         options->tcp_rcv_buf = -1;
1146 }
1147
1148 /*
1149  * Called after processing other sources of option data, this fills those
1150  * options for which no value has been specified with their default values.
1151  */
1152
1153 void
1154 fill_default_options(Options * options)
1155 {
1156         int len;
1157
1158         if (options->forward_agent == -1)
1159                 options->forward_agent = 0;
1160         if (options->forward_x11 == -1)
1161                 options->forward_x11 = 0;
1162         if (options->forward_x11_trusted == -1)
1163                 options->forward_x11_trusted = 0;
1164         if (options->exit_on_forward_failure == -1)
1165                 options->exit_on_forward_failure = 0;
1166         if (options->xauth_location == NULL)
1167                 options->xauth_location = _PATH_XAUTH;
1168         if (options->gateway_ports == -1)
1169                 options->gateway_ports = 0;
1170         if (options->use_privileged_port == -1)
1171                 options->use_privileged_port = 0;
1172         if (options->rsa_authentication == -1)
1173                 options->rsa_authentication = 1;
1174         if (options->pubkey_authentication == -1)
1175                 options->pubkey_authentication = 1;
1176         if (options->challenge_response_authentication == -1)
1177                 options->challenge_response_authentication = 1;
1178         if (options->gss_authentication == -1)
1179                 options->gss_authentication = 0;
1180         if (options->gss_keyex == -1)
1181                 options->gss_keyex = 0;
1182         if (options->gss_deleg_creds == -1)
1183                 options->gss_deleg_creds = 0;
1184         if (options->gss_trust_dns == -1)
1185                 options->gss_trust_dns = 0;
1186         if (options->gss_renewal_rekey == -1)
1187                 options->gss_renewal_rekey = 0;
1188         if (options->password_authentication == -1)
1189                 options->password_authentication = 1;
1190         if (options->kbd_interactive_authentication == -1)
1191                 options->kbd_interactive_authentication = 1;
1192         if (options->rhosts_rsa_authentication == -1)
1193                 options->rhosts_rsa_authentication = 0;
1194         if (options->hostbased_authentication == -1)
1195                 options->hostbased_authentication = 0;
1196         if (options->batch_mode == -1)
1197                 options->batch_mode = 0;
1198         if (options->check_host_ip == -1)
1199                 options->check_host_ip = 1;
1200         if (options->strict_host_key_checking == -1)
1201                 options->strict_host_key_checking = 2;  /* 2 is default */
1202         if (options->compression == -1)
1203                 options->compression = 0;
1204         if (options->tcp_keep_alive == -1)
1205                 options->tcp_keep_alive = 1;
1206         if (options->compression_level == -1)
1207                 options->compression_level = 6;
1208         if (options->port == -1)
1209                 options->port = 0;      /* Filled in ssh_connect. */
1210         if (options->address_family == -1)
1211                 options->address_family = AF_UNSPEC;
1212         if (options->connection_attempts == -1)
1213                 options->connection_attempts = 1;
1214         if (options->number_of_password_prompts == -1)
1215                 options->number_of_password_prompts = 3;
1216         /* Selected in ssh_login(). */
1217         if (options->cipher == -1)
1218                 options->cipher = SSH_CIPHER_NOT_SET;
1219         /* options->ciphers, default set in myproposals.h */
1220         /* options->macs, default set in myproposals.h */
1221         /* options->hostkeyalgorithms, default set in myproposals.h */
1222         if (options->protocol == SSH_PROTO_UNKNOWN)
1223                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
1224         if (options->num_identity_files == 0) {
1225                 if (options->protocol & SSH_PROTO_1) {
1226                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1227                         options->identity_files[options->num_identity_files] =
1228                             xmalloc(len);
1229                         snprintf(options->identity_files[options->num_identity_files++],
1230                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1231                 }
1232                 if (options->protocol & SSH_PROTO_2) {
1233                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1234                         options->identity_files[options->num_identity_files] =
1235                             xmalloc(len);
1236                         snprintf(options->identity_files[options->num_identity_files++],
1237                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1238
1239                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1240                         options->identity_files[options->num_identity_files] =
1241                             xmalloc(len);
1242                         snprintf(options->identity_files[options->num_identity_files++],
1243                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1244                 }
1245         }
1246         if (options->escape_char == -1)
1247                 options->escape_char = '~';
1248         if (options->system_hostfile == NULL)
1249                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1250         if (options->user_hostfile == NULL)
1251                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1252         if (options->system_hostfile2 == NULL)
1253                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1254         if (options->user_hostfile2 == NULL)
1255                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1256         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1257                 options->log_level = SYSLOG_LEVEL_INFO;
1258         if (options->clear_forwardings == 1)
1259                 clear_forwardings(options);
1260         if (options->no_host_authentication_for_localhost == - 1)
1261                 options->no_host_authentication_for_localhost = 0;
1262         if (options->identities_only == -1)
1263                 options->identities_only = 0;
1264         if (options->enable_ssh_keysign == -1)
1265                 options->enable_ssh_keysign = 0;
1266         if (options->rekey_limit == -1)
1267                 options->rekey_limit = 0;
1268         if (options->verify_host_key_dns == -1)
1269                 options->verify_host_key_dns = 0;
1270         if (options->server_alive_interval == -1)
1271                 options->server_alive_interval = 0;
1272         if (options->server_alive_count_max == -1)
1273                 options->server_alive_count_max = 3;
1274         if (options->none_switch == -1)
1275                 options->none_switch = 0;
1276         if (options->hpn_disabled == -1)
1277                 options->hpn_disabled = 0;
1278         if (options->hpn_buffer_size > -1)
1279         {
1280           /* if a user tries to set the size to 0 set it to 1KB */
1281                 if (options->hpn_buffer_size == 0)
1282                 options->hpn_buffer_size = 1024;
1283                 /*limit the buffer to 64MB*/
1284                 if (options->hpn_buffer_size > 65536)
1285                 {
1286                         options->hpn_buffer_size = 65536*1024;
1287                         debug("User requested buffer larger than 64MB. Request reverted to 64MB");
1288                 }
1289                 debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1290         }
1291         if (options->tcp_rcv_buf == 0)
1292                 options->tcp_rcv_buf = 1;
1293         if (options->tcp_rcv_buf > -1) 
1294                 options->tcp_rcv_buf *=1024;
1295         if (options->tcp_rcv_buf_poll == -1)
1296                 options->tcp_rcv_buf_poll = 1;
1297         if (options->control_master == -1)
1298                 options->control_master = 0;
1299         if (options->hash_known_hosts == -1)
1300                 options->hash_known_hosts = 0;
1301         if (options->tun_open == -1)
1302                 options->tun_open = SSH_TUNMODE_NO;
1303         if (options->tun_local == -1)
1304                 options->tun_local = SSH_TUNID_ANY;
1305         if (options->tun_remote == -1)
1306                 options->tun_remote = SSH_TUNID_ANY;
1307         if (options->permit_local_command == -1)
1308                 options->permit_local_command = 0;
1309         if (options->visual_host_key == -1)
1310                 options->visual_host_key = 0;
1311         if (options->zero_knowledge_password_authentication == -1)
1312                 options->zero_knowledge_password_authentication = 0;
1313         /* options->local_command should not be set by default */
1314         /* options->proxy_command should not be set by default */
1315         /* options->user will be set in the main program if appropriate */
1316         /* options->hostname will be set in the main program if appropriate */
1317         /* options->host_key_alias should not be set by default */
1318         /* options->preferred_authentications will be set in ssh */
1319 }
1320
1321 /*
1322  * parse_forward
1323  * parses a string containing a port forwarding specification of the form:
1324  *   dynamicfwd == 0
1325  *      [listenhost:]listenport:connecthost:connectport
1326  *   dynamicfwd == 1
1327  *      [listenhost:]listenport
1328  * returns number of arguments parsed or zero on error
1329  */
1330 int
1331 parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1332 {
1333         int i;
1334         char *p, *cp, *fwdarg[4];
1335
1336         memset(fwd, '\0', sizeof(*fwd));
1337
1338         cp = p = xstrdup(fwdspec);
1339
1340         /* skip leading spaces */
1341         while (isspace(*cp))
1342                 cp++;
1343
1344         for (i = 0; i < 4; ++i)
1345                 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1346                         break;
1347
1348         /* Check for trailing garbage */
1349         if (cp != NULL)
1350                 i = 0;  /* failure */
1351
1352         switch (i) {
1353         case 1:
1354                 fwd->listen_host = NULL;
1355                 fwd->listen_port = a2port(fwdarg[0]);
1356                 fwd->connect_host = xstrdup("socks");
1357                 break;
1358
1359         case 2:
1360                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1361                 fwd->listen_port = a2port(fwdarg[1]);
1362                 fwd->connect_host = xstrdup("socks");
1363                 break;
1364
1365         case 3:
1366                 fwd->listen_host = NULL;
1367                 fwd->listen_port = a2port(fwdarg[0]);
1368                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1369                 fwd->connect_port = a2port(fwdarg[2]);
1370                 break;
1371
1372         case 4:
1373                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1374                 fwd->listen_port = a2port(fwdarg[1]);
1375                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1376                 fwd->connect_port = a2port(fwdarg[3]);
1377                 break;
1378         default:
1379                 i = 0; /* failure */
1380         }
1381
1382         xfree(p);
1383
1384         if (dynamicfwd) {
1385                 if (!(i == 1 || i == 2))
1386                         goto fail_free;
1387         } else {
1388                 if (!(i == 3 || i == 4))
1389                         goto fail_free;
1390                 if (fwd->connect_port <= 0)
1391                         goto fail_free;
1392         }
1393
1394         if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1395                 goto fail_free;
1396
1397         if (fwd->connect_host != NULL &&
1398             strlen(fwd->connect_host) >= NI_MAXHOST)
1399                 goto fail_free;
1400         if (fwd->listen_host != NULL &&
1401             strlen(fwd->listen_host) >= NI_MAXHOST)
1402                 goto fail_free;
1403
1404
1405         return (i);
1406
1407  fail_free:
1408         if (fwd->connect_host != NULL) {
1409                 xfree(fwd->connect_host);
1410                 fwd->connect_host = NULL;
1411         }
1412         if (fwd->listen_host != NULL) {
1413                 xfree(fwd->listen_host);
1414                 fwd->listen_host = NULL;
1415         }
1416         return (0);
1417 }
This page took 2.970962 seconds and 5 git commands to generate.