summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2013-09-14 23:42:11 +0100
committerColin Watson <cjwatson@debian.org>2013-09-14 23:42:11 +0100
commit327155e6824b3ee13837bdde04e4eb47e147ff46 (patch)
tree8f8743122403c7a2e6ed919156711fb1520c657f /readconf.c
parent0334ce32304e9ba2a10ee5ca49ca6e8ff3ba6cf4 (diff)
parent74e339b8f8936bc0d985e053a076d0c9b5e9ea51 (diff)
* New upstream release (http://www.openssh.com/txt/release-6.3).
- sftp(1): add support for resuming partial downloads using the "reget" command and on the sftp commandline or on the "get" commandline using the "-a" (append) option (closes: #158590). - ssh(1): add an "IgnoreUnknown" configuration option to selectively suppress errors arising from unknown configuration directives (closes: #436052). - sftp(1): update progressmeter when data is acknowledged, not when it's sent (partially addresses #708372). - ssh(1): do not fatally exit when attempting to cleanup multiplexing- created channels that are incompletely opened (closes: #651357).
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 0b26a6735..2778176c6 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
@@ -32,6 +32,9 @@
32#include <unistd.h> 32#include <unistd.h>
33#include <pwd.h> 33#include <pwd.h>
34#include <grp.h> 34#include <grp.h>
35#ifdef HAVE_UTIL_H
36#include <util.h>
37#endif
35 38
36#include "xmalloc.h" 39#include "xmalloc.h"
37#include "ssh.h" 40#include "ssh.h"
@@ -139,9 +142,9 @@ typedef enum {
139 oHashKnownHosts, 142 oHashKnownHosts,
140 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 143 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
141 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, 144 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
142 oKexAlgorithms, oIPQoS, oRequestTTY, 145 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown,
143 oProtocolKeepAlives, oSetupTimeOut, 146 oProtocolKeepAlives, oSetupTimeOut,
144 oDeprecated, oUnsupported 147 oIgnoredUnknownOption, oDeprecated, oUnsupported
145} OpCodes; 148} OpCodes;
146 149
147/* Textual representations of the tokens. */ 150/* Textual representations of the tokens. */
@@ -262,6 +265,7 @@ static struct {
262 { "kexalgorithms", oKexAlgorithms }, 265 { "kexalgorithms", oKexAlgorithms },
263 { "ipqos", oIPQoS }, 266 { "ipqos", oIPQoS },
264 { "requesttty", oRequestTTY }, 267 { "requesttty", oRequestTTY },
268 { "ignoreunknown", oIgnoreUnknown },
265 { "protocolkeepalives", oProtocolKeepAlives }, 269 { "protocolkeepalives", oProtocolKeepAlives },
266 { "setuptimeout", oSetupTimeOut }, 270 { "setuptimeout", oSetupTimeOut },
267 271
@@ -322,22 +326,20 @@ clear_forwardings(Options *options)
322 int i; 326 int i;
323 327
324 for (i = 0; i < options->num_local_forwards; i++) { 328 for (i = 0; i < options->num_local_forwards; i++) {
325 if (options->local_forwards[i].listen_host != NULL) 329 free(options->local_forwards[i].listen_host);
326 xfree(options->local_forwards[i].listen_host); 330 free(options->local_forwards[i].connect_host);
327 xfree(options->local_forwards[i].connect_host);
328 } 331 }
329 if (options->num_local_forwards > 0) { 332 if (options->num_local_forwards > 0) {
330 xfree(options->local_forwards); 333 free(options->local_forwards);
331 options->local_forwards = NULL; 334 options->local_forwards = NULL;
332 } 335 }
333 options->num_local_forwards = 0; 336 options->num_local_forwards = 0;
334 for (i = 0; i < options->num_remote_forwards; i++) { 337 for (i = 0; i < options->num_remote_forwards; i++) {
335 if (options->remote_forwards[i].listen_host != NULL) 338 free(options->remote_forwards[i].listen_host);
336 xfree(options->remote_forwards[i].listen_host); 339 free(options->remote_forwards[i].connect_host);
337 xfree(options->remote_forwards[i].connect_host);
338 } 340 }
339 if (options->num_remote_forwards > 0) { 341 if (options->num_remote_forwards > 0) {
340 xfree(options->remote_forwards); 342 free(options->remote_forwards);
341 options->remote_forwards = NULL; 343 options->remote_forwards = NULL;
342 } 344 }
343 options->num_remote_forwards = 0; 345 options->num_remote_forwards = 0;
@@ -369,14 +371,17 @@ add_identity_file(Options *options, const char *dir, const char *filename,
369 */ 371 */
370 372
371static OpCodes 373static OpCodes
372parse_token(const char *cp, const char *filename, int linenum) 374parse_token(const char *cp, const char *filename, int linenum,
375 const char *ignored_unknown)
373{ 376{
374 u_int i; 377 int i;
375 378
376 for (i = 0; keywords[i].name; i++) 379 for (i = 0; keywords[i].name; i++)
377 if (strcasecmp(cp, keywords[i].name) == 0) 380 if (strcmp(cp, keywords[i].name) == 0)
378 return keywords[i].opcode; 381 return keywords[i].opcode;
379 382 if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
383 strlen(ignored_unknown), 1) == 1)
384 return oIgnoredUnknownOption;
380 error("%s: line %d: Bad configuration option: %s", 385 error("%s: line %d: Bad configuration option: %s",
381 filename, linenum, cp); 386 filename, linenum, cp);
382 return oBadOption; 387 return oBadOption;
@@ -395,10 +400,10 @@ process_config_line(Options *options, const char *host,
395{ 400{
396 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; 401 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
397 char **cpptr, fwdarg[256]; 402 char **cpptr, fwdarg[256];
398 u_int *uintptr, max_entries = 0; 403 u_int i, *uintptr, max_entries = 0;
399 int negated, opcode, *intptr, value, value2, scale; 404 int negated, opcode, *intptr, value, value2;
400 LogLevel *log_level_ptr; 405 LogLevel *log_level_ptr;
401 long long orig, val64; 406 long long val64;
402 size_t len; 407 size_t len;
403 Forward fwd; 408 Forward fwd;
404 409
@@ -418,14 +423,22 @@ process_config_line(Options *options, const char *host,
418 keyword = strdelim(&s); 423 keyword = strdelim(&s);
419 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 424 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
420 return 0; 425 return 0;
426 /* Match lowercase keyword */
427 for (i = 0; i < strlen(keyword); i++)
428 keyword[i] = tolower(keyword[i]);
421 429
422 opcode = parse_token(keyword, filename, linenum); 430 opcode = parse_token(keyword, filename, linenum,
431 options->ignored_unknown);
423 432
424 switch (opcode) { 433 switch (opcode) {
425 case oBadOption: 434 case oBadOption:
426 /* don't panic, but count bad options */ 435 /* don't panic, but count bad options */
427 return -1; 436 return -1;
428 /* NOTREACHED */ 437 /* NOTREACHED */
438 case oIgnoredUnknownOption:
439 debug("%s line %d: Ignored unknown option \"%s\"",
440 filename, linenum, keyword);
441 return 0;
429 case oConnectTimeout: 442 case oConnectTimeout:
430 intptr = &options->connection_timeout; 443 intptr = &options->connection_timeout;
431parse_time: 444parse_time:
@@ -604,39 +617,32 @@ parse_yesnoask:
604 case oRekeyLimit: 617 case oRekeyLimit:
605 arg = strdelim(&s); 618 arg = strdelim(&s);
606 if (!arg || *arg == '\0') 619 if (!arg || *arg == '\0')
607 fatal("%.200s line %d: Missing argument.", filename, linenum); 620 fatal("%.200s line %d: Missing argument.", filename,
608 if (arg[0] < '0' || arg[0] > '9') 621 linenum);
609 fatal("%.200s line %d: Bad number.", filename, linenum); 622 if (strcmp(arg, "default") == 0) {
610 orig = val64 = strtoll(arg, &endofnumber, 10); 623 val64 = 0;
611 if (arg == endofnumber) 624 } else {
612 fatal("%.200s line %d: Bad number.", filename, linenum); 625 if (scan_scaled(arg, &val64) == -1)
613 switch (toupper(*endofnumber)) { 626 fatal("%.200s line %d: Bad number '%s': %s",
614 case '\0': 627 filename, linenum, arg, strerror(errno));
615 scale = 1; 628 /* check for too-large or too-small limits */
616 break; 629 if (val64 > UINT_MAX)
617 case 'K': 630 fatal("%.200s line %d: RekeyLimit too large",
618 scale = 1<<10; 631 filename, linenum);
619 break; 632 if (val64 != 0 && val64 < 16)
620 case 'M': 633 fatal("%.200s line %d: RekeyLimit too small",
621 scale = 1<<20; 634 filename, linenum);
622 break;
623 case 'G':
624 scale = 1<<30;
625 break;
626 default:
627 fatal("%.200s line %d: Invalid RekeyLimit suffix",
628 filename, linenum);
629 } 635 }
630 val64 *= scale;
631 /* detect integer wrap and too-large limits */
632 if ((val64 / scale) != orig || val64 > UINT_MAX)
633 fatal("%.200s line %d: RekeyLimit too large",
634 filename, linenum);
635 if (val64 < 16)
636 fatal("%.200s line %d: RekeyLimit too small",
637 filename, linenum);
638 if (*activep && options->rekey_limit == -1) 636 if (*activep && options->rekey_limit == -1)
639 options->rekey_limit = (u_int32_t)val64; 637 options->rekey_limit = (u_int32_t)val64;
638 if (s != NULL) { /* optional rekey interval present */
639 if (strcmp(s, "none") == 0) {
640 (void)strdelim(&s); /* discard */
641 break;
642 }
643 intptr = &options->rekey_interval;
644 goto parse_time;
645 }
640 break; 646 break;
641 647
642 case oIdentityFile: 648 case oIdentityFile:
@@ -1106,6 +1112,10 @@ parse_int:
1106 *intptr = value; 1112 *intptr = value;
1107 break; 1113 break;
1108 1114
1115 case oIgnoreUnknown:
1116 charptr = &options->ignored_unknown;
1117 goto parse_string;
1118
1109 case oDeprecated: 1119 case oDeprecated:
1110 debug("%s line %d: Deprecated option \"%s\"", 1120 debug("%s line %d: Deprecated option \"%s\"",
1111 filename, linenum, keyword); 1121 filename, linenum, keyword);
@@ -1251,6 +1261,7 @@ initialize_options(Options * options)
1251 options->no_host_authentication_for_localhost = - 1; 1261 options->no_host_authentication_for_localhost = - 1;
1252 options->identities_only = - 1; 1262 options->identities_only = - 1;
1253 options->rekey_limit = - 1; 1263 options->rekey_limit = - 1;
1264 options->rekey_interval = -1;
1254 options->verify_host_key_dns = -1; 1265 options->verify_host_key_dns = -1;
1255 options->server_alive_interval = -1; 1266 options->server_alive_interval = -1;
1256 options->server_alive_count_max = -1; 1267 options->server_alive_count_max = -1;
@@ -1271,6 +1282,7 @@ initialize_options(Options * options)
1271 options->ip_qos_interactive = -1; 1282 options->ip_qos_interactive = -1;
1272 options->ip_qos_bulk = -1; 1283 options->ip_qos_bulk = -1;
1273 options->request_tty = -1; 1284 options->request_tty = -1;
1285 options->ignored_unknown = NULL;
1274} 1286}
1275 1287
1276/* 1288/*
@@ -1281,8 +1293,6 @@ initialize_options(Options * options)
1281void 1293void
1282fill_default_options(Options * options) 1294fill_default_options(Options * options)
1283{ 1295{
1284 int len;
1285
1286 if (options->forward_agent == -1) 1296 if (options->forward_agent == -1)
1287 options->forward_agent = 0; 1297 options->forward_agent = 0;
1288 if (options->forward_x11 == -1) 1298 if (options->forward_x11 == -1)
@@ -1396,6 +1406,8 @@ fill_default_options(Options * options)
1396 options->enable_ssh_keysign = 0; 1406 options->enable_ssh_keysign = 0;
1397 if (options->rekey_limit == -1) 1407 if (options->rekey_limit == -1)
1398 options->rekey_limit = 0; 1408 options->rekey_limit = 0;
1409 if (options->rekey_interval == -1)
1410 options->rekey_interval = 0;
1399 if (options->verify_host_key_dns == -1) 1411 if (options->verify_host_key_dns == -1)
1400 options->verify_host_key_dns = 0; 1412 options->verify_host_key_dns = 0;
1401 if (options->server_alive_interval == -1) { 1413 if (options->server_alive_interval == -1) {
@@ -1504,7 +1516,7 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1504 i = 0; /* failure */ 1516 i = 0; /* failure */
1505 } 1517 }
1506 1518
1507 xfree(p); 1519 free(p);
1508 1520
1509 if (dynamicfwd) { 1521 if (dynamicfwd) {
1510 if (!(i == 1 || i == 2)) 1522 if (!(i == 1 || i == 2))
@@ -1530,13 +1542,9 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1530 return (i); 1542 return (i);
1531 1543
1532 fail_free: 1544 fail_free:
1533 if (fwd->connect_host != NULL) { 1545 free(fwd->connect_host);
1534 xfree(fwd->connect_host); 1546 fwd->connect_host = NULL;
1535 fwd->connect_host = NULL; 1547 free(fwd->listen_host);
1536 } 1548 fwd->listen_host = NULL;
1537 if (fwd->listen_host != NULL) {
1538 xfree(fwd->listen_host);
1539 fwd->listen_host = NULL;
1540 }
1541 return (0); 1549 return (0);
1542} 1550}