]> andersk Git - openssh.git/blame - readconf.c
- markus@cvs.openbsd.org 2001/04/17 09:52:48
[openssh.git] / readconf.c
CommitLineData
8efc0c15 1/*
5260325f 2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5260325f 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5260325f 5 * Functions for reading the configuration files.
6ae2364d 6 *
bcbf86ec 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".
5260325f 12 */
8efc0c15 13
14#include "includes.h"
b7c70970 15RCSID("$OpenBSD: readconf.c,v 1.75 2001/04/15 21:28:35 stevesk Exp $");
8efc0c15 16
17#include "ssh.h"
8efc0c15 18#include "xmalloc.h"
a8be9f80 19#include "compat.h"
42f11eb2 20#include "cipher.h"
21#include "pathnames.h"
22#include "log.h"
23#include "readconf.h"
24#include "match.h"
25#include "misc.h"
b2552997 26#include "kex.h"
27#include "mac.h"
8efc0c15 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 FallBackToRsh no
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 UseRsh yes
69
70 Host *.su
71 Cipher none
72 PasswordAuthentication no
73
74 # Defaults for various options
75 Host *
76 ForwardAgent no
fa08c86b 77 ForwardX11 no
8efc0c15 78 RhostsAuthentication yes
79 PasswordAuthentication yes
80 RSAAuthentication yes
81 RhostsRSAAuthentication yes
82 FallBackToRsh no
83 UseRsh no
84 StrictHostKeyChecking yes
85 KeepAlives no
86 IdentityFile ~/.ssh/identity
87 Port 22
88 EscapeChar ~
89
90*/
91
92/* Keyword tokens. */
93
5260325f 94typedef enum {
95 oBadOption,
96 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
97 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
d464095c 98 oChallengeResponseAuthentication, oXAuthLocation,
8efc0c15 99#ifdef KRB4
5260325f 100 oKerberosAuthentication,
8efc0c15 101#endif /* KRB4 */
102#ifdef AFS
5260325f 103 oKerberosTgtPassing, oAFSTokenPassing,
8efc0c15 104#endif
5260325f 105 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
106 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
107 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
108 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
d464095c 109 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
b2552997 110 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
fa08c86b 111 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
cab80f75 112 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
8002af61 113 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication
8efc0c15 114} OpCodes;
115
116/* Textual representations of the tokens. */
117
5260325f 118static struct {
119 const char *name;
120 OpCodes opcode;
121} keywords[] = {
122 { "forwardagent", oForwardAgent },
123 { "forwardx11", oForwardX11 },
fa649821 124 { "xauthlocation", oXAuthLocation },
5260325f 125 { "gatewayports", oGatewayPorts },
126 { "useprivilegedport", oUsePrivilegedPort },
127 { "rhostsauthentication", oRhostsAuthentication },
128 { "passwordauthentication", oPasswordAuthentication },
94ec8c6b 129 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
130 { "kbdinteractivedevices", oKbdInteractiveDevices },
5260325f 131 { "rsaauthentication", oRSAAuthentication },
fa08c86b 132 { "pubkeyauthentication", oPubkeyAuthentication },
d464095c 133 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
8002af61 134 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
0140e66a 135 { "hostbasedauthentication", oHostbasedAuthentication },
d464095c 136 { "challengeresponseauthentication", oChallengeResponseAuthentication },
137 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
138 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
8efc0c15 139#ifdef KRB4
5260325f 140 { "kerberosauthentication", oKerberosAuthentication },
8efc0c15 141#endif /* KRB4 */
142#ifdef AFS
5260325f 143 { "kerberostgtpassing", oKerberosTgtPassing },
144 { "afstokenpassing", oAFSTokenPassing },
8efc0c15 145#endif
5260325f 146 { "fallbacktorsh", oFallBackToRsh },
147 { "usersh", oUseRsh },
148 { "identityfile", oIdentityFile },
fa08c86b 149 { "identityfile2", oIdentityFile }, /* alias */
5260325f 150 { "hostname", oHostName },
8abcdba4 151 { "hostkeyalias", oHostKeyAlias },
5260325f 152 { "proxycommand", oProxyCommand },
153 { "port", oPort },
154 { "cipher", oCipher },
a8be9f80 155 { "ciphers", oCiphers },
b2552997 156 { "macs", oMacs },
a8be9f80 157 { "protocol", oProtocol },
5260325f 158 { "remoteforward", oRemoteForward },
159 { "localforward", oLocalForward },
160 { "user", oUser },
161 { "host", oHost },
162 { "escapechar", oEscapeChar },
5260325f 163 { "globalknownhostsfile", oGlobalKnownHostsFile },
164 { "userknownhostsfile", oUserKnownHostsFile },
a306f2dd 165 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
166 { "userknownhostsfile2", oUserKnownHostsFile2 },
5260325f 167 { "connectionattempts", oConnectionAttempts },
168 { "batchmode", oBatchMode },
169 { "checkhostip", oCheckHostIP },
170 { "stricthostkeychecking", oStrictHostKeyChecking },
171 { "compression", oCompression },
172 { "compressionlevel", oCompressionLevel },
173 { "keepalive", oKeepAlives },
174 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
5260325f 175 { "loglevel", oLogLevel },
0490e609 176 { "dynamicforward", oDynamicForward },
cab80f75 177 { "preferredauthentications", oPreferredAuthentications },
5260325f 178 { NULL, 0 }
6a17f9c2 179};
180
aa3378df 181/*
182 * Adds a local TCP/IP port forward to options. Never returns if there is an
183 * error.
184 */
8efc0c15 185
6ae2364d 186void
57112b5a 187add_local_forward(Options *options, u_short port, const char *host,
188 u_short host_port)
8efc0c15 189{
5260325f 190 Forward *fwd;
3c62e7eb 191#ifndef HAVE_CYGWIN
5260325f 192 extern uid_t original_real_uid;
5260325f 193 if (port < IPPORT_RESERVED && original_real_uid != 0)
54b974dc 194 fatal("Privileged ports can only be forwarded by root.");
3c62e7eb 195#endif
5260325f 196 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
197 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
198 fwd = &options->local_forwards[options->num_local_forwards++];
199 fwd->port = port;
200 fwd->host = xstrdup(host);
201 fwd->host_port = host_port;
8efc0c15 202}
203
aa3378df 204/*
205 * Adds a remote TCP/IP port forward to options. Never returns if there is
206 * an error.
207 */
8efc0c15 208
6ae2364d 209void
57112b5a 210add_remote_forward(Options *options, u_short port, const char *host,
211 u_short host_port)
8efc0c15 212{
5260325f 213 Forward *fwd;
214 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
215 fatal("Too many remote forwards (max %d).",
216 SSH_MAX_FORWARDS_PER_DIRECTION);
217 fwd = &options->remote_forwards[options->num_remote_forwards++];
218 fwd->port = port;
219 fwd->host = xstrdup(host);
220 fwd->host_port = host_port;
8efc0c15 221}
222
aa3378df 223/*
6be9a5e8 224 * Returns the number of the token pointed to by cp or oBadOption.
aa3378df 225 */
8efc0c15 226
6ae2364d 227static OpCodes
5260325f 228parse_token(const char *cp, const char *filename, int linenum)
8efc0c15 229{
1e3b8b07 230 u_int i;
8efc0c15 231
5260325f 232 for (i = 0; keywords[i].name; i++)
aa3378df 233 if (strcasecmp(cp, keywords[i].name) == 0)
5260325f 234 return keywords[i].opcode;
8efc0c15 235
b7c70970 236 error("%s: line %d: Bad configuration option: %s",
237 filename, linenum, cp);
5260325f 238 return oBadOption;
8efc0c15 239}
240
aa3378df 241/*
242 * Processes a single option line as used in the configuration files. This
243 * only sets those values that have not already been set.
244 */
8efc0c15 245
e7c0f9d5 246int
247process_config_line(Options *options, const char *host,
5260325f 248 char *line, const char *filename, int linenum,
249 int *activep)
8efc0c15 250{
089fbbd2 251 char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
57112b5a 252 int opcode, *intptr, value;
253 u_short fwd_port, fwd_host_port;
5260325f 254
704b1659 255 s = line;
256 /* Get the keyword. (Each line is supposed to begin with a keyword). */
257 keyword = strdelim(&s);
258 /* Ignore leading whitespace. */
259 if (*keyword == '\0')
260 keyword = strdelim(&s);
42f11eb2 261 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
5260325f 262 return 0;
263
089fbbd2 264 opcode = parse_token(keyword, filename, linenum);
5260325f 265
266 switch (opcode) {
267 case oBadOption:
aa3378df 268 /* don't panic, but count bad options */
269 return -1;
5260325f 270 /* NOTREACHED */
271 case oForwardAgent:
272 intptr = &options->forward_agent;
273parse_flag:
704b1659 274 arg = strdelim(&s);
089fbbd2 275 if (!arg || *arg == '\0')
5260325f 276 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
277 value = 0; /* To avoid compiler warning... */
089fbbd2 278 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 279 value = 1;
089fbbd2 280 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 281 value = 0;
282 else
283 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
284 if (*activep && *intptr == -1)
285 *intptr = value;
286 break;
287
288 case oForwardX11:
289 intptr = &options->forward_x11;
290 goto parse_flag;
291
292 case oGatewayPorts:
293 intptr = &options->gateway_ports;
294 goto parse_flag;
295
296 case oUsePrivilegedPort:
297 intptr = &options->use_privileged_port;
298 goto parse_flag;
299
300 case oRhostsAuthentication:
301 intptr = &options->rhosts_authentication;
302 goto parse_flag;
303
304 case oPasswordAuthentication:
305 intptr = &options->password_authentication;
306 goto parse_flag;
307
94ec8c6b 308 case oKbdInteractiveAuthentication:
309 intptr = &options->kbd_interactive_authentication;
310 goto parse_flag;
311
312 case oKbdInteractiveDevices:
313 charptr = &options->kbd_interactive_devices;
314 goto parse_string;
315
fa08c86b 316 case oPubkeyAuthentication:
317 intptr = &options->pubkey_authentication;
1d1ffb87 318 goto parse_flag;
319
5260325f 320 case oRSAAuthentication:
321 intptr = &options->rsa_authentication;
322 goto parse_flag;
323
324 case oRhostsRSAAuthentication:
325 intptr = &options->rhosts_rsa_authentication;
326 goto parse_flag;
327
8002af61 328 case oHostbasedAuthentication:
329 intptr = &options->hostbased_authentication;
330 goto parse_flag;
331
d464095c 332 case oChallengeResponseAuthentication:
333 intptr = &options->challenge_reponse_authentication;
5260325f 334 goto parse_flag;
8efc0c15 335
336#ifdef KRB4
5260325f 337 case oKerberosAuthentication:
338 intptr = &options->kerberos_authentication;
339 goto parse_flag;
8efc0c15 340#endif /* KRB4 */
341
342#ifdef AFS
5260325f 343 case oKerberosTgtPassing:
344 intptr = &options->kerberos_tgt_passing;
345 goto parse_flag;
8efc0c15 346
5260325f 347 case oAFSTokenPassing:
348 intptr = &options->afs_token_passing;
349 goto parse_flag;
8efc0c15 350#endif
5260325f 351
352 case oFallBackToRsh:
353 intptr = &options->fallback_to_rsh;
354 goto parse_flag;
355
356 case oUseRsh:
357 intptr = &options->use_rsh;
358 goto parse_flag;
359
360 case oBatchMode:
361 intptr = &options->batch_mode;
362 goto parse_flag;
363
364 case oCheckHostIP:
365 intptr = &options->check_host_ip;
366 goto parse_flag;
367
368 case oStrictHostKeyChecking:
369 intptr = &options->strict_host_key_checking;
704b1659 370 arg = strdelim(&s);
089fbbd2 371 if (!arg || *arg == '\0')
c76c8819 372 fatal("%.200s line %d: Missing yes/no/ask argument.",
5260325f 373 filename, linenum);
374 value = 0; /* To avoid compiler warning... */
089fbbd2 375 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
5260325f 376 value = 1;
089fbbd2 377 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
5260325f 378 value = 0;
089fbbd2 379 else if (strcmp(arg, "ask") == 0)
5260325f 380 value = 2;
381 else
382 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
383 if (*activep && *intptr == -1)
384 *intptr = value;
385 break;
386
387 case oCompression:
388 intptr = &options->compression;
389 goto parse_flag;
390
391 case oKeepAlives:
392 intptr = &options->keepalives;
393 goto parse_flag;
394
395 case oNumberOfPasswordPrompts:
396 intptr = &options->number_of_password_prompts;
397 goto parse_int;
398
399 case oCompressionLevel:
400 intptr = &options->compression_level;
401 goto parse_int;
402
403 case oIdentityFile:
704b1659 404 arg = strdelim(&s);
089fbbd2 405 if (!arg || *arg == '\0')
5260325f 406 fatal("%.200s line %d: Missing argument.", filename, linenum);
407 if (*activep) {
fa08c86b 408 intptr = &options->num_identity_files;
a306f2dd 409 if (*intptr >= SSH_MAX_IDENTITY_FILES)
5260325f 410 fatal("%.200s line %d: Too many identity files specified (max %d).",
411 filename, linenum, SSH_MAX_IDENTITY_FILES);
fa08c86b 412 charptr = &options->identity_files[*intptr];
089fbbd2 413 *charptr = xstrdup(arg);
a306f2dd 414 *intptr = *intptr + 1;
5260325f 415 }
416 break;
417
fa649821 418 case oXAuthLocation:
419 charptr=&options->xauth_location;
420 goto parse_string;
421
5260325f 422 case oUser:
423 charptr = &options->user;
424parse_string:
704b1659 425 arg = strdelim(&s);
089fbbd2 426 if (!arg || *arg == '\0')
5260325f 427 fatal("%.200s line %d: Missing argument.", filename, linenum);
428 if (*activep && *charptr == NULL)
089fbbd2 429 *charptr = xstrdup(arg);
5260325f 430 break;
431
432 case oGlobalKnownHostsFile:
433 charptr = &options->system_hostfile;
434 goto parse_string;
435
436 case oUserKnownHostsFile:
437 charptr = &options->user_hostfile;
438 goto parse_string;
439
a306f2dd 440 case oGlobalKnownHostsFile2:
441 charptr = &options->system_hostfile2;
442 goto parse_string;
443
444 case oUserKnownHostsFile2:
445 charptr = &options->user_hostfile2;
446 goto parse_string;
447
5260325f 448 case oHostName:
449 charptr = &options->hostname;
450 goto parse_string;
451
8abcdba4 452 case oHostKeyAlias:
453 charptr = &options->host_key_alias;
454 goto parse_string;
455
cab80f75 456 case oPreferredAuthentications:
457 charptr = &options->preferred_authentications;
458 goto parse_string;
459
5260325f 460 case oProxyCommand:
461 charptr = &options->proxy_command;
462 string = xstrdup("");
704b1659 463 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 464 string = xrealloc(string, strlen(string) + strlen(arg) + 2);
5260325f 465 strcat(string, " ");
089fbbd2 466 strcat(string, arg);
5260325f 467 }
468 if (*activep && *charptr == NULL)
469 *charptr = string;
470 else
471 xfree(string);
472 return 0;
473
474 case oPort:
475 intptr = &options->port;
476parse_int:
704b1659 477 arg = strdelim(&s);
089fbbd2 478 if (!arg || *arg == '\0')
5260325f 479 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 480 if (arg[0] < '0' || arg[0] > '9')
5260325f 481 fatal("%.200s line %d: Bad number.", filename, linenum);
aa3378df 482
483 /* Octal, decimal, or hex format? */
089fbbd2 484 value = strtol(arg, &endofnumber, 0);
485 if (arg == endofnumber)
aa3378df 486 fatal("%.200s line %d: Bad number.", filename, linenum);
5260325f 487 if (*activep && *intptr == -1)
488 *intptr = value;
489 break;
490
491 case oConnectionAttempts:
492 intptr = &options->connection_attempts;
493 goto parse_int;
494
495 case oCipher:
496 intptr = &options->cipher;
704b1659 497 arg = strdelim(&s);
089fbbd2 498 if (!arg || *arg == '\0')
71276795 499 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 500 value = cipher_number(arg);
5260325f 501 if (value == -1)
502 fatal("%.200s line %d: Bad cipher '%s'.",
089fbbd2 503 filename, linenum, arg ? arg : "<NONE>");
5260325f 504 if (*activep && *intptr == -1)
505 *intptr = value;
506 break;
507
a8be9f80 508 case oCiphers:
704b1659 509 arg = strdelim(&s);
089fbbd2 510 if (!arg || *arg == '\0')
71276795 511 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 512 if (!ciphers_valid(arg))
d0c832f3 513 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
089fbbd2 514 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 515 if (*activep && options->ciphers == NULL)
089fbbd2 516 options->ciphers = xstrdup(arg);
a8be9f80 517 break;
518
b2552997 519 case oMacs:
520 arg = strdelim(&s);
521 if (!arg || *arg == '\0')
522 fatal("%.200s line %d: Missing argument.", filename, linenum);
523 if (!mac_valid(arg))
524 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
525 filename, linenum, arg ? arg : "<NONE>");
526 if (*activep && options->macs == NULL)
527 options->macs = xstrdup(arg);
528 break;
529
a8be9f80 530 case oProtocol:
531 intptr = &options->protocol;
704b1659 532 arg = strdelim(&s);
089fbbd2 533 if (!arg || *arg == '\0')
71276795 534 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 535 value = proto_spec(arg);
a8be9f80 536 if (value == SSH_PROTO_UNKNOWN)
537 fatal("%.200s line %d: Bad protocol spec '%s'.",
089fbbd2 538 filename, linenum, arg ? arg : "<NONE>");
a8be9f80 539 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
540 *intptr = value;
541 break;
542
5260325f 543 case oLogLevel:
544 intptr = (int *) &options->log_level;
704b1659 545 arg = strdelim(&s);
089fbbd2 546 value = log_level_number(arg);
5260325f 547 if (value == (LogLevel) - 1)
54b974dc 548 fatal("%.200s line %d: unsupported log level '%s'",
089fbbd2 549 filename, linenum, arg ? arg : "<NONE>");
5260325f 550 if (*activep && (LogLevel) * intptr == -1)
551 *intptr = (LogLevel) value;
552 break;
553
554 case oRemoteForward:
704b1659 555 arg = strdelim(&s);
089fbbd2 556 if (!arg || *arg == '\0')
5260325f 557 fatal("%.200s line %d: Missing argument.", filename, linenum);
2d2a2c65 558 fwd_port = a2port(arg);
559 if (fwd_port == 0)
5260325f 560 fatal("%.200s line %d: Badly formatted port number.",
561 filename, linenum);
704b1659 562 arg = strdelim(&s);
089fbbd2 563 if (!arg || *arg == '\0')
5260325f 564 fatal("%.200s line %d: Missing second argument.",
565 filename, linenum);
089fbbd2 566 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
5260325f 567 fatal("%.200s line %d: Badly formatted host:port.",
568 filename, linenum);
569 if (*activep)
570 add_remote_forward(options, fwd_port, buf, fwd_host_port);
571 break;
572
573 case oLocalForward:
704b1659 574 arg = strdelim(&s);
089fbbd2 575 if (!arg || *arg == '\0')
5260325f 576 fatal("%.200s line %d: Missing argument.", filename, linenum);
2d2a2c65 577 fwd_port = a2port(arg);
578 if (fwd_port == 0)
5260325f 579 fatal("%.200s line %d: Badly formatted port number.",
580 filename, linenum);
704b1659 581 arg = strdelim(&s);
089fbbd2 582 if (!arg || *arg == '\0')
5260325f 583 fatal("%.200s line %d: Missing second argument.",
584 filename, linenum);
089fbbd2 585 if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
5260325f 586 fatal("%.200s line %d: Badly formatted host:port.",
587 filename, linenum);
588 if (*activep)
589 add_local_forward(options, fwd_port, buf, fwd_host_port);
590 break;
591
0490e609 592 case oDynamicForward:
593 arg = strdelim(&s);
594 if (!arg || *arg == '\0')
595 fatal("%.200s line %d: Missing port argument.",
596 filename, linenum);
2d2a2c65 597 fwd_port = a2port(arg);
598 if (fwd_port == 0)
0490e609 599 fatal("%.200s line %d: Badly formatted port number.",
600 filename, linenum);
0490e609 601 add_local_forward(options, fwd_port, "socks4", 0);
8002af61 602 break;
0490e609 603
5260325f 604 case oHost:
605 *activep = 0;
704b1659 606 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
089fbbd2 607 if (match_pattern(host, arg)) {
608 debug("Applying options for %.100s", arg);
5260325f 609 *activep = 1;
610 break;
611 }
704b1659 612 /* Avoid garbage check below, as strdelim is done. */
5260325f 613 return 0;
614
615 case oEscapeChar:
616 intptr = &options->escape_char;
704b1659 617 arg = strdelim(&s);
089fbbd2 618 if (!arg || *arg == '\0')
5260325f 619 fatal("%.200s line %d: Missing argument.", filename, linenum);
089fbbd2 620 if (arg[0] == '^' && arg[2] == 0 &&
1e3b8b07 621 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
622 value = (u_char) arg[1] & 31;
089fbbd2 623 else if (strlen(arg) == 1)
1e3b8b07 624 value = (u_char) arg[0];
089fbbd2 625 else if (strcmp(arg, "none") == 0)
5260325f 626 value = -2;
627 else {
628 fatal("%.200s line %d: Bad escape character.",
629 filename, linenum);
630 /* NOTREACHED */
631 value = 0; /* Avoid compiler warning. */
632 }
633 if (*activep && *intptr == -1)
634 *intptr = value;
635 break;
636
637 default:
638 fatal("process_config_line: Unimplemented opcode %d", opcode);
639 }
640
641 /* Check that there is no garbage at end of line. */
42f11eb2 642 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
089fbbd2 643 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
644 filename, linenum, arg);
645 }
5260325f 646 return 0;
8efc0c15 647}
648
649
aa3378df 650/*
651 * Reads the config file and modifies the options accordingly. Options
652 * should already be initialized before this call. This never returns if
653 * there is an error. If the file does not exist, this returns immediately.
654 */
8efc0c15 655
6ae2364d 656void
5260325f 657read_config_file(const char *filename, const char *host, Options *options)
8efc0c15 658{
5260325f 659 FILE *f;
660 char line[1024];
661 int active, linenum;
662 int bad_options = 0;
663
664 /* Open the file. */
665 f = fopen(filename, "r");
666 if (!f)
667 return;
668
669 debug("Reading configuration data %.200s", filename);
670
aa3378df 671 /*
672 * Mark that we are now processing the options. This flag is turned
673 * on/off by Host specifications.
674 */
5260325f 675 active = 1;
676 linenum = 0;
677 while (fgets(line, sizeof(line), f)) {
678 /* Update line number counter. */
679 linenum++;
680 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
681 bad_options++;
682 }
683 fclose(f);
684 if (bad_options > 0)
54b974dc 685 fatal("%s: terminating, %d bad configuration options",
5260325f 686 filename, bad_options);
8efc0c15 687}
688
aa3378df 689/*
690 * Initializes options to special values that indicate that they have not yet
691 * been set. Read_config_file will only set options with this value. Options
692 * are processed in the following order: command line, user config file,
693 * system config file. Last, fill_default_options is called.
694 */
8efc0c15 695
6ae2364d 696void
5260325f 697initialize_options(Options * options)
8efc0c15 698{
5260325f 699 memset(options, 'X', sizeof(*options));
700 options->forward_agent = -1;
701 options->forward_x11 = -1;
fa649821 702 options->xauth_location = NULL;
5260325f 703 options->gateway_ports = -1;
704 options->use_privileged_port = -1;
705 options->rhosts_authentication = -1;
706 options->rsa_authentication = -1;
fa08c86b 707 options->pubkey_authentication = -1;
d464095c 708 options->challenge_reponse_authentication = -1;
8efc0c15 709#ifdef KRB4
5260325f 710 options->kerberos_authentication = -1;
8efc0c15 711#endif
712#ifdef AFS
5260325f 713 options->kerberos_tgt_passing = -1;
714 options->afs_token_passing = -1;
8efc0c15 715#endif
5260325f 716 options->password_authentication = -1;
94ec8c6b 717 options->kbd_interactive_authentication = -1;
718 options->kbd_interactive_devices = NULL;
5260325f 719 options->rhosts_rsa_authentication = -1;
8002af61 720 options->hostbased_authentication = -1;
5260325f 721 options->fallback_to_rsh = -1;
722 options->use_rsh = -1;
723 options->batch_mode = -1;
724 options->check_host_ip = -1;
725 options->strict_host_key_checking = -1;
726 options->compression = -1;
727 options->keepalives = -1;
728 options->compression_level = -1;
729 options->port = -1;
730 options->connection_attempts = -1;
731 options->number_of_password_prompts = -1;
732 options->cipher = -1;
a8be9f80 733 options->ciphers = NULL;
b2552997 734 options->macs = NULL;
a8be9f80 735 options->protocol = SSH_PROTO_UNKNOWN;
5260325f 736 options->num_identity_files = 0;
737 options->hostname = NULL;
8abcdba4 738 options->host_key_alias = NULL;
5260325f 739 options->proxy_command = NULL;
740 options->user = NULL;
741 options->escape_char = -1;
742 options->system_hostfile = NULL;
743 options->user_hostfile = NULL;
a306f2dd 744 options->system_hostfile2 = NULL;
745 options->user_hostfile2 = NULL;
5260325f 746 options->num_local_forwards = 0;
747 options->num_remote_forwards = 0;
748 options->log_level = (LogLevel) - 1;
cab80f75 749 options->preferred_authentications = NULL;
8efc0c15 750}
751
aa3378df 752/*
753 * Called after processing other sources of option data, this fills those
754 * options for which no value has been specified with their default values.
755 */
8efc0c15 756
6ae2364d 757void
5260325f 758fill_default_options(Options * options)
8efc0c15 759{
d2c46e77 760 int len;
761
5260325f 762 if (options->forward_agent == -1)
71276795 763 options->forward_agent = 0;
5260325f 764 if (options->forward_x11 == -1)
c8d54615 765 options->forward_x11 = 0;
fa649821 766#ifdef XAUTH_PATH
767 if (options->xauth_location == NULL)
768 options->xauth_location = XAUTH_PATH;
769#endif /* XAUTH_PATH */
5260325f 770 if (options->gateway_ports == -1)
771 options->gateway_ports = 0;
772 if (options->use_privileged_port == -1)
d5ebca2b 773 options->use_privileged_port = 0;
5260325f 774 if (options->rhosts_authentication == -1)
775 options->rhosts_authentication = 1;
776 if (options->rsa_authentication == -1)
777 options->rsa_authentication = 1;
fa08c86b 778 if (options->pubkey_authentication == -1)
779 options->pubkey_authentication = 1;
d464095c 780 if (options->challenge_reponse_authentication == -1)
781 options->challenge_reponse_authentication = 0;
8efc0c15 782#ifdef KRB4
5260325f 783 if (options->kerberos_authentication == -1)
784 options->kerberos_authentication = 1;
8efc0c15 785#endif /* KRB4 */
786#ifdef AFS
5260325f 787 if (options->kerberos_tgt_passing == -1)
788 options->kerberos_tgt_passing = 1;
789 if (options->afs_token_passing == -1)
790 options->afs_token_passing = 1;
8efc0c15 791#endif /* AFS */
5260325f 792 if (options->password_authentication == -1)
793 options->password_authentication = 1;
94ec8c6b 794 if (options->kbd_interactive_authentication == -1)
d464095c 795 options->kbd_interactive_authentication = 1;
5260325f 796 if (options->rhosts_rsa_authentication == -1)
797 options->rhosts_rsa_authentication = 1;
8002af61 798 if (options->hostbased_authentication == -1)
799 options->hostbased_authentication = 0;
5260325f 800 if (options->fallback_to_rsh == -1)
3f7a7e4a 801 options->fallback_to_rsh = 0;
5260325f 802 if (options->use_rsh == -1)
803 options->use_rsh = 0;
804 if (options->batch_mode == -1)
805 options->batch_mode = 0;
806 if (options->check_host_ip == -1)
807 options->check_host_ip = 1;
808 if (options->strict_host_key_checking == -1)
809 options->strict_host_key_checking = 2; /* 2 is default */
810 if (options->compression == -1)
811 options->compression = 0;
812 if (options->keepalives == -1)
813 options->keepalives = 1;
814 if (options->compression_level == -1)
815 options->compression_level = 6;
816 if (options->port == -1)
817 options->port = 0; /* Filled in ssh_connect. */
818 if (options->connection_attempts == -1)
819 options->connection_attempts = 4;
820 if (options->number_of_password_prompts == -1)
821 options->number_of_password_prompts = 3;
822 /* Selected in ssh_login(). */
823 if (options->cipher == -1)
824 options->cipher = SSH_CIPHER_NOT_SET;
d0c832f3 825 /* options->ciphers, default set in myproposals.h */
b2552997 826 /* options->macs, default set in myproposals.h */
a8be9f80 827 if (options->protocol == SSH_PROTO_UNKNOWN)
3e587cc3 828 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
5260325f 829 if (options->num_identity_files == 0) {
fa08c86b 830 if (options->protocol & SSH_PROTO_1) {
d2c46e77 831 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
fa08c86b 832 options->identity_files[options->num_identity_files] =
d2c46e77 833 xmalloc(len);
834 snprintf(options->identity_files[options->num_identity_files++],
835 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
fa08c86b 836 }
837 if (options->protocol & SSH_PROTO_2) {
ec63b02d 838 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
839 options->identity_files[options->num_identity_files] =
840 xmalloc(len);
841 snprintf(options->identity_files[options->num_identity_files++],
842 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
843
d2c46e77 844 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
fa08c86b 845 options->identity_files[options->num_identity_files] =
d2c46e77 846 xmalloc(len);
847 snprintf(options->identity_files[options->num_identity_files++],
848 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
fa08c86b 849 }
a306f2dd 850 }
5260325f 851 if (options->escape_char == -1)
852 options->escape_char = '~';
853 if (options->system_hostfile == NULL)
42f11eb2 854 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
5260325f 855 if (options->user_hostfile == NULL)
42f11eb2 856 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
a306f2dd 857 if (options->system_hostfile2 == NULL)
42f11eb2 858 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
a306f2dd 859 if (options->user_hostfile2 == NULL)
42f11eb2 860 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
5260325f 861 if (options->log_level == (LogLevel) - 1)
59c97189 862 options->log_level = SYSLOG_LEVEL_INFO;
5260325f 863 /* options->proxy_command should not be set by default */
864 /* options->user will be set in the main program if appropriate */
865 /* options->hostname will be set in the main program if appropriate */
8abcdba4 866 /* options->host_key_alias should not be set by default */
cab80f75 867 /* options->preferred_authentications will be set in ssh */
8efc0c15 868}
This page took 0.292601 seconds and 5 git commands to generate.