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