summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'readconf.c')
-rw-r--r--readconf.c128
1 files changed, 68 insertions, 60 deletions
diff --git a/readconf.c b/readconf.c
index 375ca32cc..2695fd6c0 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.196 2013/02/22 04:45:08 dtucker Exp $ */ 1/* $OpenBSD: readconf.c,v 1.204 2013/06/10 19:19:44 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -30,6 +30,9 @@
30#include <stdio.h> 30#include <stdio.h>
31#include <string.h> 31#include <string.h>
32#include <unistd.h> 32#include <unistd.h>
33#ifdef HAVE_UTIL_H
34#include <util.h>
35#endif
33 36
34#include "xmalloc.h" 37#include "xmalloc.h"
35#include "ssh.h" 38#include "ssh.h"
@@ -136,8 +139,8 @@ typedef enum {
136 oHashKnownHosts, 139 oHashKnownHosts,
137 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 140 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
138 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, 141 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
139 oKexAlgorithms, oIPQoS, oRequestTTY, 142 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown,
140 oDeprecated, oUnsupported 143 oIgnoredUnknownOption, oDeprecated, oUnsupported
141} OpCodes; 144} OpCodes;
142 145
143/* Textual representations of the tokens. */ 146/* Textual representations of the tokens. */
@@ -257,6 +260,7 @@ static struct {
257 { "kexalgorithms", oKexAlgorithms }, 260 { "kexalgorithms", oKexAlgorithms },
258 { "ipqos", oIPQoS }, 261 { "ipqos", oIPQoS },
259 { "requesttty", oRequestTTY }, 262 { "requesttty", oRequestTTY },
263 { "ignoreunknown", oIgnoreUnknown },
260 264
261 { NULL, oBadOption } 265 { NULL, oBadOption }
262}; 266};
@@ -315,22 +319,20 @@ clear_forwardings(Options *options)
315 int i; 319 int i;
316 320
317 for (i = 0; i < options->num_local_forwards; i++) { 321 for (i = 0; i < options->num_local_forwards; i++) {
318 if (options->local_forwards[i].listen_host != NULL) 322 free(options->local_forwards[i].listen_host);
319 xfree(options->local_forwards[i].listen_host); 323 free(options->local_forwards[i].connect_host);
320 xfree(options->local_forwards[i].connect_host);
321 } 324 }
322 if (options->num_local_forwards > 0) { 325 if (options->num_local_forwards > 0) {
323 xfree(options->local_forwards); 326 free(options->local_forwards);
324 options->local_forwards = NULL; 327 options->local_forwards = NULL;
325 } 328 }
326 options->num_local_forwards = 0; 329 options->num_local_forwards = 0;
327 for (i = 0; i < options->num_remote_forwards; i++) { 330 for (i = 0; i < options->num_remote_forwards; i++) {
328 if (options->remote_forwards[i].listen_host != NULL) 331 free(options->remote_forwards[i].listen_host);
329 xfree(options->remote_forwards[i].listen_host); 332 free(options->remote_forwards[i].connect_host);
330 xfree(options->remote_forwards[i].connect_host);
331 } 333 }
332 if (options->num_remote_forwards > 0) { 334 if (options->num_remote_forwards > 0) {
333 xfree(options->remote_forwards); 335 free(options->remote_forwards);
334 options->remote_forwards = NULL; 336 options->remote_forwards = NULL;
335 } 337 }
336 options->num_remote_forwards = 0; 338 options->num_remote_forwards = 0;
@@ -362,14 +364,17 @@ add_identity_file(Options *options, const char *dir, const char *filename,
362 */ 364 */
363 365
364static OpCodes 366static OpCodes
365parse_token(const char *cp, const char *filename, int linenum) 367parse_token(const char *cp, const char *filename, int linenum,
368 const char *ignored_unknown)
366{ 369{
367 u_int i; 370 int i;
368 371
369 for (i = 0; keywords[i].name; i++) 372 for (i = 0; keywords[i].name; i++)
370 if (strcasecmp(cp, keywords[i].name) == 0) 373 if (strcmp(cp, keywords[i].name) == 0)
371 return keywords[i].opcode; 374 return keywords[i].opcode;
372 375 if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
376 strlen(ignored_unknown), 1) == 1)
377 return oIgnoredUnknownOption;
373 error("%s: line %d: Bad configuration option: %s", 378 error("%s: line %d: Bad configuration option: %s",
374 filename, linenum, cp); 379 filename, linenum, cp);
375 return oBadOption; 380 return oBadOption;
@@ -388,10 +393,10 @@ process_config_line(Options *options, const char *host,
388{ 393{
389 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; 394 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
390 char **cpptr, fwdarg[256]; 395 char **cpptr, fwdarg[256];
391 u_int *uintptr, max_entries = 0; 396 u_int i, *uintptr, max_entries = 0;
392 int negated, opcode, *intptr, value, value2, scale; 397 int negated, opcode, *intptr, value, value2;
393 LogLevel *log_level_ptr; 398 LogLevel *log_level_ptr;
394 long long orig, val64; 399 long long val64;
395 size_t len; 400 size_t len;
396 Forward fwd; 401 Forward fwd;
397 402
@@ -411,14 +416,22 @@ process_config_line(Options *options, const char *host,
411 keyword = strdelim(&s); 416 keyword = strdelim(&s);
412 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 417 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
413 return 0; 418 return 0;
419 /* Match lowercase keyword */
420 for (i = 0; i < strlen(keyword); i++)
421 keyword[i] = tolower(keyword[i]);
414 422
415 opcode = parse_token(keyword, filename, linenum); 423 opcode = parse_token(keyword, filename, linenum,
424 options->ignored_unknown);
416 425
417 switch (opcode) { 426 switch (opcode) {
418 case oBadOption: 427 case oBadOption:
419 /* don't panic, but count bad options */ 428 /* don't panic, but count bad options */
420 return -1; 429 return -1;
421 /* NOTREACHED */ 430 /* NOTREACHED */
431 case oIgnoredUnknownOption:
432 debug("%s line %d: Ignored unknown option \"%s\"",
433 filename, linenum, keyword);
434 return 0;
422 case oConnectTimeout: 435 case oConnectTimeout:
423 intptr = &options->connection_timeout; 436 intptr = &options->connection_timeout;
424parse_time: 437parse_time:
@@ -593,39 +606,32 @@ parse_yesnoask:
593 case oRekeyLimit: 606 case oRekeyLimit:
594 arg = strdelim(&s); 607 arg = strdelim(&s);
595 if (!arg || *arg == '\0') 608 if (!arg || *arg == '\0')
596 fatal("%.200s line %d: Missing argument.", filename, linenum); 609 fatal("%.200s line %d: Missing argument.", filename,
597 if (arg[0] < '0' || arg[0] > '9') 610 linenum);
598 fatal("%.200s line %d: Bad number.", filename, linenum); 611 if (strcmp(arg, "default") == 0) {
599 orig = val64 = strtoll(arg, &endofnumber, 10); 612 val64 = 0;
600 if (arg == endofnumber) 613 } else {
601 fatal("%.200s line %d: Bad number.", filename, linenum); 614 if (scan_scaled(arg, &val64) == -1)
602 switch (toupper(*endofnumber)) { 615 fatal("%.200s line %d: Bad number '%s': %s",
603 case '\0': 616 filename, linenum, arg, strerror(errno));
604 scale = 1; 617 /* check for too-large or too-small limits */
605 break; 618 if (val64 > UINT_MAX)
606 case 'K': 619 fatal("%.200s line %d: RekeyLimit too large",
607 scale = 1<<10; 620 filename, linenum);
608 break; 621 if (val64 != 0 && val64 < 16)
609 case 'M': 622 fatal("%.200s line %d: RekeyLimit too small",
610 scale = 1<<20; 623 filename, linenum);
611 break;
612 case 'G':
613 scale = 1<<30;
614 break;
615 default:
616 fatal("%.200s line %d: Invalid RekeyLimit suffix",
617 filename, linenum);
618 } 624 }
619 val64 *= scale;
620 /* detect integer wrap and too-large limits */
621 if ((val64 / scale) != orig || val64 > UINT_MAX)
622 fatal("%.200s line %d: RekeyLimit too large",
623 filename, linenum);
624 if (val64 < 16)
625 fatal("%.200s line %d: RekeyLimit too small",
626 filename, linenum);
627 if (*activep && options->rekey_limit == -1) 625 if (*activep && options->rekey_limit == -1)
628 options->rekey_limit = (u_int32_t)val64; 626 options->rekey_limit = (u_int32_t)val64;
627 if (s != NULL) { /* optional rekey interval present */
628 if (strcmp(s, "none") == 0) {
629 (void)strdelim(&s); /* discard */
630 break;
631 }
632 intptr = &options->rekey_interval;
633 goto parse_time;
634 }
629 break; 635 break;
630 636
631 case oIdentityFile: 637 case oIdentityFile:
@@ -1093,6 +1099,10 @@ parse_int:
1093 *intptr = value; 1099 *intptr = value;
1094 break; 1100 break;
1095 1101
1102 case oIgnoreUnknown:
1103 charptr = &options->ignored_unknown;
1104 goto parse_string;
1105
1096 case oDeprecated: 1106 case oDeprecated:
1097 debug("%s line %d: Deprecated option \"%s\"", 1107 debug("%s line %d: Deprecated option \"%s\"",
1098 filename, linenum, keyword); 1108 filename, linenum, keyword);
@@ -1238,6 +1248,7 @@ initialize_options(Options * options)
1238 options->no_host_authentication_for_localhost = - 1; 1248 options->no_host_authentication_for_localhost = - 1;
1239 options->identities_only = - 1; 1249 options->identities_only = - 1;
1240 options->rekey_limit = - 1; 1250 options->rekey_limit = - 1;
1251 options->rekey_interval = -1;
1241 options->verify_host_key_dns = -1; 1252 options->verify_host_key_dns = -1;
1242 options->server_alive_interval = -1; 1253 options->server_alive_interval = -1;
1243 options->server_alive_count_max = -1; 1254 options->server_alive_count_max = -1;
@@ -1258,6 +1269,7 @@ initialize_options(Options * options)
1258 options->ip_qos_interactive = -1; 1269 options->ip_qos_interactive = -1;
1259 options->ip_qos_bulk = -1; 1270 options->ip_qos_bulk = -1;
1260 options->request_tty = -1; 1271 options->request_tty = -1;
1272 options->ignored_unknown = NULL;
1261} 1273}
1262 1274
1263/* 1275/*
@@ -1268,8 +1280,6 @@ initialize_options(Options * options)
1268void 1280void
1269fill_default_options(Options * options) 1281fill_default_options(Options * options)
1270{ 1282{
1271 int len;
1272
1273 if (options->forward_agent == -1) 1283 if (options->forward_agent == -1)
1274 options->forward_agent = 0; 1284 options->forward_agent = 0;
1275 if (options->forward_x11 == -1) 1285 if (options->forward_x11 == -1)
@@ -1381,6 +1391,8 @@ fill_default_options(Options * options)
1381 options->enable_ssh_keysign = 0; 1391 options->enable_ssh_keysign = 0;
1382 if (options->rekey_limit == -1) 1392 if (options->rekey_limit == -1)
1383 options->rekey_limit = 0; 1393 options->rekey_limit = 0;
1394 if (options->rekey_interval == -1)
1395 options->rekey_interval = 0;
1384 if (options->verify_host_key_dns == -1) 1396 if (options->verify_host_key_dns == -1)
1385 options->verify_host_key_dns = 0; 1397 options->verify_host_key_dns = 0;
1386 if (options->server_alive_interval == -1) 1398 if (options->server_alive_interval == -1)
@@ -1484,7 +1496,7 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1484 i = 0; /* failure */ 1496 i = 0; /* failure */
1485 } 1497 }
1486 1498
1487 xfree(p); 1499 free(p);
1488 1500
1489 if (dynamicfwd) { 1501 if (dynamicfwd) {
1490 if (!(i == 1 || i == 2)) 1502 if (!(i == 1 || i == 2))
@@ -1510,13 +1522,9 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1510 return (i); 1522 return (i);
1511 1523
1512 fail_free: 1524 fail_free:
1513 if (fwd->connect_host != NULL) { 1525 free(fwd->connect_host);
1514 xfree(fwd->connect_host); 1526 fwd->connect_host = NULL;
1515 fwd->connect_host = NULL; 1527 free(fwd->listen_host);
1516 } 1528 fwd->listen_host = NULL;
1517 if (fwd->listen_host != NULL) {
1518 xfree(fwd->listen_host);
1519 fwd->listen_host = NULL;
1520 }
1521 return (0); 1529 return (0);
1522} 1530}