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