diff options
Diffstat (limited to 'readconf.c')
-rw-r--r-- | readconf.c | 128 |
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 | ||
364 | static OpCodes | 366 | static OpCodes |
365 | parse_token(const char *cp, const char *filename, int linenum) | 367 | parse_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; |
424 | parse_time: | 437 | parse_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) | |||
1268 | void | 1280 | void |
1269 | fill_default_options(Options * options) | 1281 | fill_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 | } |