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