source: trunk/third/openssh/readconf.c @ 18763

Revision 18763, 28.1 KB checked in by zacheiss, 22 years ago (diff)
Merge openssh 3.5p1.
Line 
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 *                    All rights reserved
5 * Functions for reading the configuration files.
6 *
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose.  Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
12 */
13
14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $");
16
17#include "ssh.h"
18#include "xmalloc.h"
19#include "compat.h"
20#include "cipher.h"
21#include "pathnames.h"
22#include "log.h"
23#include "readconf.h"
24#include "match.h"
25#include "misc.h"
26#include "kex.h"
27#include "mac.h"
28
29/* Format of the configuration file:
30
31   # Configuration data is parsed as follows:
32   #  1. command line options
33   #  2. user-specific file
34   #  3. system-wide file
35   # Any configuration value is only changed the first time it is set.
36   # Thus, host-specific definitions should be at the beginning of the
37   # configuration file, and defaults at the end.
38
39   # Host-specific declarations.  These may override anything above.  A single
40   # host may match multiple declarations; these are processed in the order
41   # that they are given in.
42
43   Host *.ngs.fi ngs.fi
44     User foo
45
46   Host fake.com
47     HostName another.host.name.real.org
48     User blaah
49     Port 34289
50     ForwardX11 no
51     ForwardAgent no
52
53   Host books.com
54     RemoteForward 9999 shadows.cs.hut.fi:9999
55     Cipher 3des
56
57   Host fascist.blob.com
58     Port 23123
59     User tylonen
60     RhostsAuthentication no
61     PasswordAuthentication no
62
63   Host puukko.hut.fi
64     User t35124p
65     ProxyCommand ssh-proxy %h %p
66
67   Host *.fr
68     PublicKeyAuthentication no
69
70   Host *.su
71     Cipher none
72     PasswordAuthentication no
73
74   # Defaults for various options
75   Host *
76     ForwardAgent no
77     ForwardX11 no
78     RhostsAuthentication yes
79     PasswordAuthentication yes
80     RSAAuthentication yes
81     RhostsRSAAuthentication yes
82     StrictHostKeyChecking yes
83     KeepAlives no
84     IdentityFile ~/.ssh/identity
85     Port 22
86     EscapeChar ~
87
88*/
89
90/* Keyword tokens. */
91
92typedef enum {
93        oBadOption,
94        oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
95        oPasswordAuthentication, oRSAAuthentication,
96        oChallengeResponseAuthentication, oXAuthLocation,
97#if defined(KRB4) || defined(KRB5)
98        oKerberosAuthentication,
99#endif
100#ifdef GSSAPI
101        oGssAuthentication, oGssDelegateCreds,
102#ifdef GSI
103        oGssGlobusDelegateLimitedCreds,
104#endif /* GSI */
105#endif /* GSSAPI */
106#if defined(AFS) || defined(KRB5)
107        oKerberosTgtPassing,
108#endif
109#ifdef AFS
110        oAFSTokenPassing,
111#endif
112        oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
113        oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
114        oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
115        oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
116        oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
117        oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
118        oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
119        oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
120        oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
121        oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
122        oClearAllForwardings, oNoHostAuthenticationForLocalhost,
123        oDeprecated
124} OpCodes;
125
126/* Textual representations of the tokens. */
127
128static struct {
129        const char *name;
130        OpCodes opcode;
131} keywords[] = {
132        { "forwardagent", oForwardAgent },
133        { "forwardx11", oForwardX11 },
134        { "xauthlocation", oXAuthLocation },
135        { "gatewayports", oGatewayPorts },
136        { "useprivilegedport", oUsePrivilegedPort },
137        { "rhostsauthentication", oRhostsAuthentication },
138        { "passwordauthentication", oPasswordAuthentication },
139        { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
140        { "kbdinteractivedevices", oKbdInteractiveDevices },
141        { "rsaauthentication", oRSAAuthentication },
142        { "pubkeyauthentication", oPubkeyAuthentication },
143        { "dsaauthentication", oPubkeyAuthentication },             /* alias */
144        { "rhostsrsaauthentication", oRhostsRSAAuthentication },
145        { "hostbasedauthentication", oHostbasedAuthentication },
146        { "challengeresponseauthentication", oChallengeResponseAuthentication },
147        { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
148        { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
149#if defined(KRB4) || defined(KRB5)
150        { "kerberosauthentication", oKerberosAuthentication },
151#endif
152#ifdef GSSAPI
153        { "gssapiauthentication", oGssAuthentication },
154        { "gssapidelegatecredentials", oGssDelegateCreds },
155#ifdef GSI
156        /* For backwards compatability with old 1.2.27 client code */
157        { "forwardgssapiglobusproxy", oGssDelegateCreds }, /* alias */
158        { "forwardgssapiglobuslimitedproxy", oGssGlobusDelegateLimitedCreds },
159#endif /* GSI */
160#endif /* GSSAPI */
161#if defined(AFS) || defined(KRB5)
162        { "kerberostgtpassing", oKerberosTgtPassing },
163#endif
164#ifdef AFS
165        { "afstokenpassing", oAFSTokenPassing },
166#endif
167        { "fallbacktorsh", oDeprecated },
168        { "usersh", oDeprecated },
169        { "identityfile", oIdentityFile },
170        { "identityfile2", oIdentityFile },                     /* alias */
171        { "hostname", oHostName },
172        { "hostkeyalias", oHostKeyAlias },
173        { "proxycommand", oProxyCommand },
174        { "port", oPort },
175        { "cipher", oCipher },
176        { "ciphers", oCiphers },
177        { "macs", oMacs },
178        { "protocol", oProtocol },
179        { "remoteforward", oRemoteForward },
180        { "localforward", oLocalForward },
181        { "user", oUser },
182        { "host", oHost },
183        { "escapechar", oEscapeChar },
184        { "globalknownhostsfile", oGlobalKnownHostsFile },
185        { "userknownhostsfile", oUserKnownHostsFile },          /* obsolete */
186        { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
187        { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
188        { "connectionattempts", oConnectionAttempts },
189        { "batchmode", oBatchMode },
190        { "checkhostip", oCheckHostIP },
191        { "stricthostkeychecking", oStrictHostKeyChecking },
192        { "compression", oCompression },
193        { "compressionlevel", oCompressionLevel },
194        { "keepalive", oKeepAlives },
195        { "numberofpasswordprompts", oNumberOfPasswordPrompts },
196        { "loglevel", oLogLevel },
197        { "dynamicforward", oDynamicForward },
198        { "preferredauthentications", oPreferredAuthentications },
199        { "hostkeyalgorithms", oHostKeyAlgorithms },
200        { "bindaddress", oBindAddress },
201        { "smartcarddevice", oSmartcardDevice },
202        { "clearallforwardings", oClearAllForwardings },
203        { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
204        { NULL, oBadOption }
205};
206
207/*
208 * Adds a local TCP/IP port forward to options.  Never returns if there is an
209 * error.
210 */
211
212void
213add_local_forward(Options *options, u_short port, const char *host,
214                  u_short host_port)
215{
216        Forward *fwd;
217#ifndef NO_IPPORT_RESERVED_CONCEPT
218        extern uid_t original_real_uid;
219        if (port < IPPORT_RESERVED && original_real_uid != 0)
220                fatal("Privileged ports can only be forwarded by root.");
221#endif
222        if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
223                fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
224        fwd = &options->local_forwards[options->num_local_forwards++];
225        fwd->port = port;
226        fwd->host = xstrdup(host);
227        fwd->host_port = host_port;
228}
229
230/*
231 * Adds a remote TCP/IP port forward to options.  Never returns if there is
232 * an error.
233 */
234
235void
236add_remote_forward(Options *options, u_short port, const char *host,
237                   u_short host_port)
238{
239        Forward *fwd;
240        if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
241                fatal("Too many remote forwards (max %d).",
242                    SSH_MAX_FORWARDS_PER_DIRECTION);
243        fwd = &options->remote_forwards[options->num_remote_forwards++];
244        fwd->port = port;
245        fwd->host = xstrdup(host);
246        fwd->host_port = host_port;
247}
248
249static void
250clear_forwardings(Options *options)
251{
252        int i;
253
254        for (i = 0; i < options->num_local_forwards; i++)
255                xfree(options->local_forwards[i].host);
256        options->num_local_forwards = 0;
257        for (i = 0; i < options->num_remote_forwards; i++)
258                xfree(options->remote_forwards[i].host);
259        options->num_remote_forwards = 0;
260}
261
262/*
263 * Returns the number of the token pointed to by cp or oBadOption.
264 */
265
266static OpCodes
267parse_token(const char *cp, const char *filename, int linenum)
268{
269        u_int i;
270
271        for (i = 0; keywords[i].name; i++)
272                if (strcasecmp(cp, keywords[i].name) == 0)
273                        return keywords[i].opcode;
274
275        error("%s: line %d: Bad configuration option: %s",
276            filename, linenum, cp);
277        return oBadOption;
278}
279
280/*
281 * Processes a single option line as used in the configuration files. This
282 * only sets those values that have not already been set.
283 */
284
285int
286process_config_line(Options *options, const char *host,
287                    char *line, const char *filename, int linenum,
288                    int *activep)
289{
290        char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
291        int opcode, *intptr, value;
292        u_short fwd_port, fwd_host_port;
293        char sfwd_host_port[6];
294
295        s = line;
296        /* Get the keyword. (Each line is supposed to begin with a keyword). */
297        keyword = strdelim(&s);
298        /* Ignore leading whitespace. */
299        if (*keyword == '\0')
300                keyword = strdelim(&s);
301        if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
302                return 0;
303
304        opcode = parse_token(keyword, filename, linenum);
305
306        switch (opcode) {
307        case oBadOption:
308                /* don't panic, but count bad options */
309                return -1;
310                /* NOTREACHED */
311        case oForwardAgent:
312                intptr = &options->forward_agent;
313parse_flag:
314                arg = strdelim(&s);
315                if (!arg || *arg == '\0')
316                        fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
317                value = 0;      /* To avoid compiler warning... */
318                if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
319                        value = 1;
320                else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
321                        value = 0;
322                else
323                        fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
324                if (*activep && *intptr == -1)
325                        *intptr = value;
326                break;
327
328        case oForwardX11:
329                intptr = &options->forward_x11;
330                goto parse_flag;
331
332        case oGatewayPorts:
333                intptr = &options->gateway_ports;
334                goto parse_flag;
335
336        case oUsePrivilegedPort:
337                intptr = &options->use_privileged_port;
338                goto parse_flag;
339
340        case oRhostsAuthentication:
341                intptr = &options->rhosts_authentication;
342                goto parse_flag;
343
344        case oPasswordAuthentication:
345                intptr = &options->password_authentication;
346                goto parse_flag;
347
348        case oKbdInteractiveAuthentication:
349                intptr = &options->kbd_interactive_authentication;
350                goto parse_flag;
351
352        case oKbdInteractiveDevices:
353                charptr = &options->kbd_interactive_devices;
354                goto parse_string;
355
356        case oPubkeyAuthentication:
357                intptr = &options->pubkey_authentication;
358                goto parse_flag;
359
360        case oRSAAuthentication:
361                intptr = &options->rsa_authentication;
362                goto parse_flag;
363
364        case oRhostsRSAAuthentication:
365                intptr = &options->rhosts_rsa_authentication;
366                goto parse_flag;
367
368        case oHostbasedAuthentication:
369                intptr = &options->hostbased_authentication;
370                goto parse_flag;
371
372        case oChallengeResponseAuthentication:
373                intptr = &options->challenge_response_authentication;
374                goto parse_flag;
375#if defined(KRB4) || defined(KRB5)
376        case oKerberosAuthentication:
377                intptr = &options->kerberos_authentication;
378                goto parse_flag;
379#endif
380#ifdef GSSAPI
381        case oGssAuthentication:
382                intptr = &options->gss_authentication;
383                goto parse_flag;
384     
385        case oGssDelegateCreds:
386                intptr = &options->gss_deleg_creds;
387                goto parse_flag;
388 
389#ifdef GSI
390        case oGssGlobusDelegateLimitedCreds:
391                intptr = &options->gss_globus_deleg_limited_proxy;
392                goto parse_flag;
393#endif /* GSI */
394
395#endif /* GSSAPI */
396
397#if defined(AFS) || defined(KRB5)
398        case oKerberosTgtPassing:
399                intptr = &options->kerberos_tgt_passing;
400                goto parse_flag;
401#endif
402#ifdef AFS
403        case oAFSTokenPassing:
404                intptr = &options->afs_token_passing;
405                goto parse_flag;
406#endif
407        case oBatchMode:
408                intptr = &options->batch_mode;
409                goto parse_flag;
410
411        case oCheckHostIP:
412                intptr = &options->check_host_ip;
413                goto parse_flag;
414
415        case oStrictHostKeyChecking:
416                intptr = &options->strict_host_key_checking;
417                arg = strdelim(&s);
418                if (!arg || *arg == '\0')
419                        fatal("%.200s line %d: Missing yes/no/ask argument.",
420                            filename, linenum);
421                value = 0;      /* To avoid compiler warning... */
422                if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
423                        value = 1;
424                else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
425                        value = 0;
426                else if (strcmp(arg, "ask") == 0)
427                        value = 2;
428                else
429                        fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
430                if (*activep && *intptr == -1)
431                        *intptr = value;
432                break;
433
434        case oCompression:
435                intptr = &options->compression;
436                goto parse_flag;
437
438        case oKeepAlives:
439                intptr = &options->keepalives;
440                goto parse_flag;
441
442        case oNoHostAuthenticationForLocalhost:
443                intptr = &options->no_host_authentication_for_localhost;
444                goto parse_flag;
445
446        case oNumberOfPasswordPrompts:
447                intptr = &options->number_of_password_prompts;
448                goto parse_int;
449
450        case oCompressionLevel:
451                intptr = &options->compression_level;
452                goto parse_int;
453
454        case oIdentityFile:
455                arg = strdelim(&s);
456                if (!arg || *arg == '\0')
457                        fatal("%.200s line %d: Missing argument.", filename, linenum);
458                if (*activep) {
459                        intptr = &options->num_identity_files;
460                        if (*intptr >= SSH_MAX_IDENTITY_FILES)
461                                fatal("%.200s line %d: Too many identity files specified (max %d).",
462                                    filename, linenum, SSH_MAX_IDENTITY_FILES);
463                        charptr =  &options->identity_files[*intptr];
464                        *charptr = xstrdup(arg);
465                        *intptr = *intptr + 1;
466                }
467                break;
468
469        case oXAuthLocation:
470                charptr=&options->xauth_location;
471                goto parse_string;
472
473        case oUser:
474                charptr = &options->user;
475parse_string:
476                arg = strdelim(&s);
477                if (!arg || *arg == '\0')
478                        fatal("%.200s line %d: Missing argument.", filename, linenum);
479                if (*activep && *charptr == NULL)
480                        *charptr = xstrdup(arg);
481                break;
482
483        case oGlobalKnownHostsFile:
484                charptr = &options->system_hostfile;
485                goto parse_string;
486
487        case oUserKnownHostsFile:
488                charptr = &options->user_hostfile;
489                goto parse_string;
490
491        case oGlobalKnownHostsFile2:
492                charptr = &options->system_hostfile2;
493                goto parse_string;
494
495        case oUserKnownHostsFile2:
496                charptr = &options->user_hostfile2;
497                goto parse_string;
498
499        case oHostName:
500                charptr = &options->hostname;
501                goto parse_string;
502
503        case oHostKeyAlias:
504                charptr = &options->host_key_alias;
505                goto parse_string;
506
507        case oPreferredAuthentications:
508                charptr = &options->preferred_authentications;
509                goto parse_string;
510
511        case oBindAddress:
512                charptr = &options->bind_address;
513                goto parse_string;
514
515        case oSmartcardDevice:
516                charptr = &options->smartcard_device;
517                goto parse_string;
518
519        case oProxyCommand:
520                charptr = &options->proxy_command;
521                string = xstrdup("");
522                while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
523                        string = xrealloc(string, strlen(string) + strlen(arg) + 2);
524                        strcat(string, " ");
525                        strcat(string, arg);
526                }
527                if (*activep && *charptr == NULL)
528                        *charptr = string;
529                else
530                        xfree(string);
531                return 0;
532
533        case oPort:
534                intptr = &options->port;
535parse_int:
536                arg = strdelim(&s);
537                if (!arg || *arg == '\0')
538                        fatal("%.200s line %d: Missing argument.", filename, linenum);
539                if (arg[0] < '0' || arg[0] > '9')
540                        fatal("%.200s line %d: Bad number.", filename, linenum);
541
542                /* Octal, decimal, or hex format? */
543                value = strtol(arg, &endofnumber, 0);
544                if (arg == endofnumber)
545                        fatal("%.200s line %d: Bad number.", filename, linenum);
546                if (*activep && *intptr == -1)
547                        *intptr = value;
548                break;
549
550        case oConnectionAttempts:
551                intptr = &options->connection_attempts;
552                goto parse_int;
553
554        case oCipher:
555                intptr = &options->cipher;
556                arg = strdelim(&s);
557                if (!arg || *arg == '\0')
558                        fatal("%.200s line %d: Missing argument.", filename, linenum);
559                value = cipher_number(arg);
560                if (value == -1)
561                        fatal("%.200s line %d: Bad cipher '%s'.",
562                            filename, linenum, arg ? arg : "<NONE>");
563                if (*activep && *intptr == -1)
564                        *intptr = value;
565                break;
566
567        case oCiphers:
568                arg = strdelim(&s);
569                if (!arg || *arg == '\0')
570                        fatal("%.200s line %d: Missing argument.", filename, linenum);
571                if (!ciphers_valid(arg))
572                        fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
573                            filename, linenum, arg ? arg : "<NONE>");
574                if (*activep && options->ciphers == NULL)
575                        options->ciphers = xstrdup(arg);
576                break;
577
578        case oMacs:
579                arg = strdelim(&s);
580                if (!arg || *arg == '\0')
581                        fatal("%.200s line %d: Missing argument.", filename, linenum);
582                if (!mac_valid(arg))
583                        fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
584                            filename, linenum, arg ? arg : "<NONE>");
585                if (*activep && options->macs == NULL)
586                        options->macs = xstrdup(arg);
587                break;
588
589        case oHostKeyAlgorithms:
590                arg = strdelim(&s);
591                if (!arg || *arg == '\0')
592                        fatal("%.200s line %d: Missing argument.", filename, linenum);
593                if (!key_names_valid2(arg))
594                        fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
595                            filename, linenum, arg ? arg : "<NONE>");
596                if (*activep && options->hostkeyalgorithms == NULL)
597                        options->hostkeyalgorithms = xstrdup(arg);
598                break;
599
600        case oProtocol:
601                intptr = &options->protocol;
602                arg = strdelim(&s);
603                if (!arg || *arg == '\0')
604                        fatal("%.200s line %d: Missing argument.", filename, linenum);
605                value = proto_spec(arg);
606                if (value == SSH_PROTO_UNKNOWN)
607                        fatal("%.200s line %d: Bad protocol spec '%s'.",
608                            filename, linenum, arg ? arg : "<NONE>");
609                if (*activep && *intptr == SSH_PROTO_UNKNOWN)
610                        *intptr = value;
611                break;
612
613        case oLogLevel:
614                intptr = (int *) &options->log_level;
615                arg = strdelim(&s);
616                value = log_level_number(arg);
617                if (value == SYSLOG_LEVEL_NOT_SET)
618                        fatal("%.200s line %d: unsupported log level '%s'",
619                            filename, linenum, arg ? arg : "<NONE>");
620                if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
621                        *intptr = (LogLevel) value;
622                break;
623
624        case oLocalForward:
625        case oRemoteForward:
626                arg = strdelim(&s);
627                if (!arg || *arg == '\0')
628                        fatal("%.200s line %d: Missing port argument.",
629                            filename, linenum);
630                if ((fwd_port = a2port(arg)) == 0)
631                        fatal("%.200s line %d: Bad listen port.",
632                            filename, linenum);
633                arg = strdelim(&s);
634                if (!arg || *arg == '\0')
635                        fatal("%.200s line %d: Missing second argument.",
636                            filename, linenum);
637                if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
638                    sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
639                        fatal("%.200s line %d: Bad forwarding specification.",
640                            filename, linenum);
641                if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
642                        fatal("%.200s line %d: Bad forwarding port.",
643                            filename, linenum);
644                if (*activep) {
645                        if (opcode == oLocalForward)
646                                add_local_forward(options, fwd_port, buf,
647                                    fwd_host_port);
648                        else if (opcode == oRemoteForward)
649                                add_remote_forward(options, fwd_port, buf,
650                                    fwd_host_port);
651                }
652                break;
653
654        case oDynamicForward:
655                arg = strdelim(&s);
656                if (!arg || *arg == '\0')
657                        fatal("%.200s line %d: Missing port argument.",
658                            filename, linenum);
659                fwd_port = a2port(arg);
660                if (fwd_port == 0)
661                        fatal("%.200s line %d: Badly formatted port number.",
662                            filename, linenum);
663                if (*activep)
664                        add_local_forward(options, fwd_port, "socks4", 0);
665                break;
666
667        case oClearAllForwardings:
668                intptr = &options->clear_forwardings;
669                goto parse_flag;
670
671        case oHost:
672                *activep = 0;
673                while ((arg = strdelim(&s)) != NULL && *arg != '\0')
674                        if (match_pattern(host, arg)) {
675                                debug("Applying options for %.100s", arg);
676                                *activep = 1;
677                                break;
678                        }
679                /* Avoid garbage check below, as strdelim is done. */
680                return 0;
681
682        case oEscapeChar:
683                intptr = &options->escape_char;
684                arg = strdelim(&s);
685                if (!arg || *arg == '\0')
686                        fatal("%.200s line %d: Missing argument.", filename, linenum);
687                if (arg[0] == '^' && arg[2] == 0 &&
688                    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
689                        value = (u_char) arg[1] & 31;
690                else if (strlen(arg) == 1)
691                        value = (u_char) arg[0];
692                else if (strcmp(arg, "none") == 0)
693                        value = SSH_ESCAPECHAR_NONE;
694                else {
695                        fatal("%.200s line %d: Bad escape character.",
696                            filename, linenum);
697                        /* NOTREACHED */
698                        value = 0;      /* Avoid compiler warning. */
699                }
700                if (*activep && *intptr == -1)
701                        *intptr = value;
702                break;
703
704        case oDeprecated:
705                debug("%s line %d: Deprecated option \"%s\"",
706                    filename, linenum, keyword);
707                return 0;
708
709        default:
710                fatal("process_config_line: Unimplemented opcode %d", opcode);
711        }
712
713        /* Check that there is no garbage at end of line. */
714        if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
715                fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
716                     filename, linenum, arg);
717        }
718        return 0;
719}
720
721
722/*
723 * Reads the config file and modifies the options accordingly.  Options
724 * should already be initialized before this call.  This never returns if
725 * there is an error.  If the file does not exist, this returns 0.
726 */
727
728int
729read_config_file(const char *filename, const char *host, Options *options)
730{
731        FILE *f;
732        char line[1024];
733        int active, linenum;
734        int bad_options = 0;
735
736        /* Open the file. */
737        f = fopen(filename, "r");
738        if (!f)
739                return 0;
740
741        debug("Reading configuration data %.200s", filename);
742
743        /*
744         * Mark that we are now processing the options.  This flag is turned
745         * on/off by Host specifications.
746         */
747        active = 1;
748        linenum = 0;
749        while (fgets(line, sizeof(line), f)) {
750                /* Update line number counter. */
751                linenum++;
752                if (process_config_line(options, host, line, filename, linenum, &active) != 0)
753                        bad_options++;
754        }
755        fclose(f);
756        if (bad_options > 0)
757                fatal("%s: terminating, %d bad configuration options",
758                    filename, bad_options);
759        return 1;
760}
761
762/*
763 * Initializes options to special values that indicate that they have not yet
764 * been set.  Read_config_file will only set options with this value. Options
765 * are processed in the following order: command line, user config file,
766 * system config file.  Last, fill_default_options is called.
767 */
768
769void
770initialize_options(Options * options)
771{
772        memset(options, 'X', sizeof(*options));
773        options->forward_agent = -1;
774        options->forward_x11 = -1;
775        options->xauth_location = NULL;
776        options->gateway_ports = -1;
777        options->use_privileged_port = -1;
778        options->rhosts_authentication = -1;
779        options->rsa_authentication = -1;
780        options->pubkey_authentication = -1;
781        options->challenge_response_authentication = -1;
782#ifdef GSSAPI
783        options->gss_authentication = -1;
784        options->gss_deleg_creds = -1;
785#ifdef GSI
786        options->gss_globus_deleg_limited_proxy = -1;
787#endif /* GSI */
788#endif /* GSSAPI */
789
790#if defined(KRB4) || defined(KRB5)
791        options->kerberos_authentication = -1;
792#endif
793#if defined(AFS) || defined(KRB5)
794        options->kerberos_tgt_passing = -1;
795#endif
796#ifdef AFS
797        options->afs_token_passing = -1;
798#endif
799        options->password_authentication = -1;
800        options->kbd_interactive_authentication = -1;
801        options->kbd_interactive_devices = NULL;
802        options->rhosts_rsa_authentication = -1;
803        options->hostbased_authentication = -1;
804        options->batch_mode = -1;
805        options->check_host_ip = -1;
806        options->strict_host_key_checking = -1;
807        options->compression = -1;
808        options->keepalives = -1;
809        options->compression_level = -1;
810        options->port = -1;
811        options->connection_attempts = -1;
812        options->number_of_password_prompts = -1;
813        options->cipher = -1;
814        options->ciphers = NULL;
815        options->macs = NULL;
816        options->hostkeyalgorithms = NULL;
817        options->protocol = SSH_PROTO_UNKNOWN;
818        options->num_identity_files = 0;
819        options->hostname = NULL;
820        options->host_key_alias = NULL;
821        options->proxy_command = NULL;
822        options->user = NULL;
823        options->escape_char = -1;
824        options->system_hostfile = NULL;
825        options->user_hostfile = NULL;
826        options->system_hostfile2 = NULL;
827        options->user_hostfile2 = NULL;
828        options->num_local_forwards = 0;
829        options->num_remote_forwards = 0;
830        options->clear_forwardings = -1;
831        options->log_level = SYSLOG_LEVEL_NOT_SET;
832        options->preferred_authentications = NULL;
833        options->bind_address = NULL;
834        options->smartcard_device = NULL;
835        options->no_host_authentication_for_localhost = - 1;
836}
837
838/*
839 * Called after processing other sources of option data, this fills those
840 * options for which no value has been specified with their default values.
841 */
842
843void
844fill_default_options(Options * options)
845{
846        int len;
847
848        if (options->forward_agent == -1)
849                options->forward_agent = 0;
850        if (options->forward_x11 == -1)
851                options->forward_x11 = 0;
852        if (options->xauth_location == NULL)
853                options->xauth_location = _PATH_XAUTH;
854        if (options->gateway_ports == -1)
855                options->gateway_ports = 0;
856        if (options->use_privileged_port == -1)
857                options->use_privileged_port = 0;
858        if (options->rhosts_authentication == -1)
859                options->rhosts_authentication = 0;
860        if (options->rsa_authentication == -1)
861                options->rsa_authentication = 1;
862        if (options->pubkey_authentication == -1)
863                options->pubkey_authentication = 1;
864        if (options->challenge_response_authentication == -1)
865                options->challenge_response_authentication = 1;
866#ifdef GSSAPI
867        if (options->gss_authentication == -1)
868                options->gss_authentication = 1;
869        if (options->gss_deleg_creds == -1)
870                options->gss_deleg_creds = 1;
871#ifdef GSI
872        if (options->gss_globus_deleg_limited_proxy == -1)
873                options->gss_globus_deleg_limited_proxy = 0;
874#endif /* GSI */
875#endif /* GSSAPI */
876#if defined(KRB4) || defined(KRB5)
877        if (options->kerberos_authentication == -1)
878                options->kerberos_authentication = 1;
879#endif
880#if defined(AFS) || defined(KRB5)
881        if (options->kerberos_tgt_passing == -1)
882                options->kerberos_tgt_passing = 1;
883#endif
884#ifdef AFS
885        if (options->afs_token_passing == -1)
886                options->afs_token_passing = 1;
887#endif
888        if (options->password_authentication == -1)
889                options->password_authentication = 1;
890        if (options->kbd_interactive_authentication == -1)
891                options->kbd_interactive_authentication = 1;
892        if (options->rhosts_rsa_authentication == -1)
893                options->rhosts_rsa_authentication = 0;
894        if (options->hostbased_authentication == -1)
895                options->hostbased_authentication = 0;
896        if (options->batch_mode == -1)
897                options->batch_mode = 0;
898        if (options->check_host_ip == -1)
899                options->check_host_ip = 1;
900        if (options->strict_host_key_checking == -1)
901                options->strict_host_key_checking = 2;  /* 2 is default */
902        if (options->compression == -1)
903                options->compression = 0;
904        if (options->keepalives == -1)
905                options->keepalives = 1;
906        if (options->compression_level == -1)
907                options->compression_level = 6;
908        if (options->port == -1)
909                options->port = 0;      /* Filled in ssh_connect. */
910        if (options->connection_attempts == -1)
911                options->connection_attempts = 1;
912        if (options->number_of_password_prompts == -1)
913                options->number_of_password_prompts = 3;
914        /* Selected in ssh_login(). */
915        if (options->cipher == -1)
916                options->cipher = SSH_CIPHER_NOT_SET;
917        /* options->ciphers, default set in myproposals.h */
918        /* options->macs, default set in myproposals.h */
919        /* options->hostkeyalgorithms, default set in myproposals.h */
920        if (options->protocol == SSH_PROTO_UNKNOWN)
921                options->protocol = SSH_PROTO_1|SSH_PROTO_2;
922        if (options->num_identity_files == 0) {
923                if (options->protocol & SSH_PROTO_1) {
924                        len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
925                        options->identity_files[options->num_identity_files] =
926                            xmalloc(len);
927                        snprintf(options->identity_files[options->num_identity_files++],
928                            len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
929                }
930                if (options->protocol & SSH_PROTO_2) {
931                        len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
932                        options->identity_files[options->num_identity_files] =
933                            xmalloc(len);
934                        snprintf(options->identity_files[options->num_identity_files++],
935                            len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
936
937                        len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
938                        options->identity_files[options->num_identity_files] =
939                            xmalloc(len);
940                        snprintf(options->identity_files[options->num_identity_files++],
941                            len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
942                }
943        }
944        if (options->escape_char == -1)
945                options->escape_char = '~';
946        if (options->system_hostfile == NULL)
947                options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
948        if (options->user_hostfile == NULL)
949                options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
950        if (options->system_hostfile2 == NULL)
951                options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
952        if (options->user_hostfile2 == NULL)
953                options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
954        if (options->log_level == SYSLOG_LEVEL_NOT_SET)
955                options->log_level = SYSLOG_LEVEL_INFO;
956        if (options->clear_forwardings == 1)
957                clear_forwardings(options);
958        if (options->no_host_authentication_for_localhost == - 1)
959                options->no_host_authentication_for_localhost = 0;
960        /* options->proxy_command should not be set by default */
961        /* options->user will be set in the main program if appropriate */
962        /* options->hostname will be set in the main program if appropriate */
963        /* options->host_key_alias should not be set by default */
964        /* options->preferred_authentications will be set in ssh */
965}
Note: See TracBrowser for help on using the repository browser.