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