View | Details | Raw Unified | Return to bug 2267 | Differences between
and this patch

Collapse All | Expand All

(-)readconf.c (-14 / +26 lines)
Lines 476-482 execute_in_shell(const char *cmd) Link Here
476
 */
476
 */
477
static int
477
static int
478
match_cfg_line(Options *options, char **condition, struct passwd *pw,
478
match_cfg_line(Options *options, char **condition, struct passwd *pw,
479
    const char *host_arg, const char *filename, int linenum)
479
    const char *original_host, int post_canon,
480
    const char *filename, int linenum)
480
{
481
{
481
	char *arg, *attrib, *cmd, *cp = *condition, *host;
482
	char *arg, *attrib, *cmd, *cp = *condition, *host;
482
	const char *ruser;
483
	const char *ruser;
Lines 493-505 match_cfg_line(Options *options, char ** Link Here
493
	if (options->hostname != NULL) {
494
	if (options->hostname != NULL) {
494
		/* NB. Please keep in sync with ssh.c:main() */
495
		/* NB. Please keep in sync with ssh.c:main() */
495
		host = percent_expand(options->hostname,
496
		host = percent_expand(options->hostname,
496
		    "h", host_arg, (char *)NULL);
497
		    "h", original_host, (char *)NULL);
497
	} else
498
	} else
498
		host = xstrdup(host_arg);
499
		host = xstrdup(original_host);
499
500
500
	debug3("checking match for '%s' host %s", cp, host);
501
	debug3("checking match for '%s' host %s", cp, host);
501
	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
502
	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
502
		attributes++;
503
		attributes++;
504
		/* criteria "all" and "canonical" have no argument */
503
		if (strcasecmp(attrib, "all") == 0) {
505
		if (strcasecmp(attrib, "all") == 0) {
504
			if (attributes != 1 ||
506
			if (attributes != 1 ||
505
			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
507
			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
Lines 511-517 match_cfg_line(Options *options, char ** Link Here
511
			*condition = cp;
513
			*condition = cp;
512
			result = 1;
514
			result = 1;
513
			goto out;
515
			goto out;
516
		} else if (strcasecmp(attrib, "canonical") == 0) {
517
			if (!post_canon) {
518
				result = 0;
519
				continue;
520
			} else
521
				debug("%.200s line %d: matched 'Canonical' ",
522
				    filename, linenum);
514
		}
523
		}
524
		/* All other criteria require an argument */
515
		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
525
		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
516
			error("Missing Match criteria for %s", attrib);
526
			error("Missing Match criteria for %s", attrib);
517
			result = -1;
527
			result = -1;
Lines 525-536 match_cfg_line(Options *options, char ** Link Here
525
				debug("%.200s line %d: matched 'Host %.100s' ",
535
				debug("%.200s line %d: matched 'Host %.100s' ",
526
				    filename, linenum, host);
536
				    filename, linenum, host);
527
		} else if (strcasecmp(attrib, "originalhost") == 0) {
537
		} else if (strcasecmp(attrib, "originalhost") == 0) {
528
			if (match_hostname(host_arg, arg, len) != 1)
538
			if (match_hostname(original_host, arg, len) != 1)
529
				result = 0;
539
				result = 0;
530
			else
540
			else
531
				debug("%.200s line %d: matched "
541
				debug("%.200s line %d: matched "
532
				    "'OriginalHost %.100s' ",
542
				    "'OriginalHost %.100s' ",
533
				    filename, linenum, host_arg);
543
				    filename, linenum, original_host);
534
		} else if (strcasecmp(attrib, "user") == 0) {
544
		} else if (strcasecmp(attrib, "user") == 0) {
535
			if (match_pattern_list(ruser, arg, len, 0) != 1)
545
			if (match_pattern_list(ruser, arg, len, 0) != 1)
536
				result = 0;
546
				result = 0;
Lines 556-562 match_cfg_line(Options *options, char ** Link Here
556
			    "d", pw->pw_dir,
566
			    "d", pw->pw_dir,
557
			    "h", host,
567
			    "h", host,
558
			    "l", thishost,
568
			    "l", thishost,
559
			    "n", host_arg,
569
			    "n", original_host,
560
			    "p", portstr,
570
			    "p", portstr,
561
			    "r", ruser,
571
			    "r", ruser,
562
			    "u", pw->pw_name,
572
			    "u", pw->pw_name,
Lines 719-725 static const struct multistate multistat Link Here
719
#define WHITESPACE " \t\r\n"
729
#define WHITESPACE " \t\r\n"
720
int
730
int
721
process_config_line(Options *options, struct passwd *pw, const char *host,
731
process_config_line(Options *options, struct passwd *pw, const char *host,
722
    char *line, const char *filename, int linenum, int *activep, int userconfig)
732
    const char *original_host, char *line, const char *filename,
733
    int linenum, int *activep, int flags)
723
{
734
{
724
	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
735
	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
725
	char **cpptr, fwdarg[256];
736
	char **cpptr, fwdarg[256];
Lines 947-953 parse_time: Link Here
947
			if (*intptr >= SSH_MAX_IDENTITY_FILES)
958
			if (*intptr >= SSH_MAX_IDENTITY_FILES)
948
				fatal("%.200s line %d: Too many identity files specified (max %d).",
959
				fatal("%.200s line %d: Too many identity files specified (max %d).",
949
				    filename, linenum, SSH_MAX_IDENTITY_FILES);
960
				    filename, linenum, SSH_MAX_IDENTITY_FILES);
950
			add_identity_file(options, NULL, arg, userconfig);
961
			add_identity_file(options, NULL,
962
			    arg, flags & SSHCONF_USERCONF);
951
		}
963
		}
952
		break;
964
		break;
953
965
Lines 1195-1202 parse_int: Link Here
1195
		if (cmdline)
1207
		if (cmdline)
1196
			fatal("Host directive not supported as a command-line "
1208
			fatal("Host directive not supported as a command-line "
1197
			    "option");
1209
			    "option");
1198
		value = match_cfg_line(options, &s, pw, host,
1210
		value = match_cfg_line(options, &s, pw, original_host,
1199
		    filename, linenum);
1211
		    flags & SSHCONF_POSTCANON, filename, linenum);
1200
		if (value < 0)
1212
		if (value < 0)
1201
			fatal("%.200s line %d: Bad Match condition", filename,
1213
			fatal("%.200s line %d: Bad Match condition", filename,
1202
			    linenum);
1214
			    linenum);
Lines 1444-1450 parse_int: Link Here
1444
		return 0;
1456
		return 0;
1445
1457
1446
	default:
1458
	default:
1447
		fatal("process_config_line: Unimplemented opcode %d", opcode);
1459
		fatal("%s: Unimplemented opcode %d", __func__, opcode);
1448
	}
1460
	}
1449
1461
1450
	/* Check that there is no garbage at end of line. */
1462
	/* Check that there is no garbage at end of line. */
Lines 1464-1470 parse_int: Link Here
1464
1476
1465
int
1477
int
1466
read_config_file(const char *filename, struct passwd *pw, const char *host,
1478
read_config_file(const char *filename, struct passwd *pw, const char *host,
1467
    Options *options, int flags)
1479
    const char *original_host, Options *options, int flags)
1468
{
1480
{
1469
	FILE *f;
1481
	FILE *f;
1470
	char line[1024];
1482
	char line[1024];
Lines 1495-1502 read_config_file(const char *filename, s Link Here
1495
	while (fgets(line, sizeof(line), f)) {
1507
	while (fgets(line, sizeof(line), f)) {
1496
		/* Update line number counter. */
1508
		/* Update line number counter. */
1497
		linenum++;
1509
		linenum++;
1498
		if (process_config_line(options, pw, host, line, filename,
1510
		if (process_config_line(options, pw, host, original_host,
1499
		    linenum, &active, flags & SSHCONF_USERCONF) != 0)
1511
		    line, filename, linenum, &active, flags) != 0)
1500
			bad_options++;
1512
			bad_options++;
1501
	}
1513
	}
1502
	fclose(f);
1514
	fclose(f);
(-)readconf.h (-3 / +4 lines)
Lines 164-177 typedef struct { Link Here
164
164
165
#define SSHCONF_CHECKPERM	1  /* check permissions on config file */
165
#define SSHCONF_CHECKPERM	1  /* check permissions on config file */
166
#define SSHCONF_USERCONF	2  /* user provided config file not system */
166
#define SSHCONF_USERCONF	2  /* user provided config file not system */
167
#define SSHCONF_POSTCANON	4  /* After hostname canonicalisation */
167
168
168
void     initialize_options(Options *);
169
void     initialize_options(Options *);
169
void     fill_default_options(Options *);
170
void     fill_default_options(Options *);
170
void	 fill_default_options_for_canonicalization(Options *);
171
void	 fill_default_options_for_canonicalization(Options *);
171
int	 process_config_line(Options *, struct passwd *, const char *, char *,
172
int	 process_config_line(Options *, struct passwd *, const char *,
172
    const char *, int, int *, int);
173
    const char *, char *, const char *, int, int *, int);
173
int	 read_config_file(const char *, struct passwd *, const char *,
174
int	 read_config_file(const char *, struct passwd *, const char *,
174
    Options *, int);
175
    const char *, Options *, int);
175
int	 parse_forward(struct Forward *, const char *, int, int);
176
int	 parse_forward(struct Forward *, const char *, int, int);
176
int	 default_ssh_port(void);
177
int	 default_ssh_port(void);
177
int	 option_clear_or_none(const char *);
178
int	 option_clear_or_none(const char *);
(-)ssh.c (-18 / +16 lines)
Lines 384-410 resolve_canonicalize(char **hostp, int p Link Here
384
 * file if the user specifies a config file on the command line.
384
 * file if the user specifies a config file on the command line.
385
 */
385
 */
386
static void
386
static void
387
process_config_files(struct passwd *pw)
387
process_config_files(const char *host_arg, struct passwd *pw, int post_canon)
388
{
388
{
389
	char buf[MAXPATHLEN];
389
	char buf[MAXPATHLEN];
390
	int r;
390
	int r;
391
391
392
	if (config != NULL) {
392
	if (config != NULL) {
393
		if (strcasecmp(config, "none") != 0 &&
393
		if (strcasecmp(config, "none") != 0 &&
394
		    !read_config_file(config, pw, host, &options,
394
		    !read_config_file(config, pw, host, host_arg, &options,
395
		    SSHCONF_USERCONF))
395
		    SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)))
396
			fatal("Can't open user config file %.100s: "
396
			fatal("Can't open user config file %.100s: "
397
			    "%.100s", config, strerror(errno));
397
			    "%.100s", config, strerror(errno));
398
	} else {
398
	} else {
399
		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
399
		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
400
		    _PATH_SSH_USER_CONFFILE);
400
		    _PATH_SSH_USER_CONFFILE);
401
		if (r > 0 && (size_t)r < sizeof(buf))
401
		if (r > 0 && (size_t)r < sizeof(buf))
402
			(void)read_config_file(buf, pw, host, &options,
402
			(void)read_config_file(buf, pw, host, host_arg,
403
			     SSHCONF_CHECKPERM|SSHCONF_USERCONF);
403
			    &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |
404
			    (post_canon ? SSHCONF_POSTCANON : 0));
404
405
405
		/* Read systemwide configuration file after user config. */
406
		/* Read systemwide configuration file after user config. */
406
		(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host,
407
		(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
407
		    &options, 0);
408
		    host, host_arg, &options,
409
		    post_canon ? SSHCONF_POSTCANON : 0);
408
	}
410
	}
409
}
411
}
410
412
Lines 788-796 main(int ac, char **av) Link Here
788
			break;
790
			break;
789
		case 'o':
791
		case 'o':
790
			line = xstrdup(optarg);
792
			line = xstrdup(optarg);
791
			if (process_config_line(&options, pw, host ? host : "",
793
			if (process_config_line(&options, pw,
792
			    line, "command-line", 0, NULL, SSHCONF_USERCONF)
794
			    host ? host : "", host ? host : "", line,
793
			    != 0)
795
			    "command-line", 0, NULL, SSHCONF_USERCONF) != 0)
794
				exit(255);
796
				exit(255);
795
			free(line);
797
			free(line);
796
			break;
798
			break;
Lines 899-905 main(int ac, char **av) Link Here
899
		);
901
		);
900
902
901
	/* Parse the configuration files */
903
	/* Parse the configuration files */
902
	process_config_files(pw);
904
	process_config_files(host_arg, pw, 0);
903
905
904
	/* Hostname canonicalisation needs a few options filled. */
906
	/* Hostname canonicalisation needs a few options filled. */
905
	fill_default_options_for_canonicalization(&options);
907
	fill_default_options_for_canonicalization(&options);
Lines 944-956 main(int ac, char **av) Link Here
944
			check_follow_cname(&host, cname);
946
			check_follow_cname(&host, cname);
945
	}
947
	}
946
948
947
	/*
949
	if (options.canonicalize_hostname != 0) {
948
	 * If the target hostname has changed as a result of canonicalisation
950
		debug("re-reading configuration");
949
	 * then re-parse the configuration files as new stanzas may match.
951
		process_config_files(host_arg, pw, 1);
950
	 */
951
	if (strcasecmp(host_arg, host) != 0) {
952
		debug("Hostname has changed; re-reading configuration");
953
		process_config_files(pw);
954
	}
952
	}
955
953
956
	/* Fill configuration defaults. */
954
	/* Fill configuration defaults. */
(-)ssh_config.5 (-6 / +34 lines)
Lines 65-71 The configuration files contain sections Link Here
65
.Dq Host
65
.Dq Host
66
specifications, and that section is only applied for hosts that
66
specifications, and that section is only applied for hosts that
67
match one of the patterns given in the specification.
67
match one of the patterns given in the specification.
68
The matched host name is the one given on the command line.
68
The matched host name is the one given on the command line
69
(possibly modified by the
70
.Cm CanonicalizeHostname
71
option.)
69
.Pp
72
.Pp
70
Since the first obtained value for each parameter is used, more
73
Since the first obtained value for each parameter is used, more
71
host-specific declarations should be given near the beginning of the
74
host-specific declarations should be given near the beginning of the
Lines 111-118 as a pattern can be used to provide glob Link Here
111
defaults for all hosts.
114
defaults for all hosts.
112
The host is the
115
The host is the
113
.Ar hostname
116
.Ar hostname
114
argument given on the command line (i.e. the name is not converted to
117
argument given on the command line (possibly modified by the
115
a canonicalized host name before matching).
118
.Cm CanonicalizeHostname
119
option.)
116
.Pp
120
.Pp
117
A pattern entry may be negated by prefixing it with an exclamation mark
121
A pattern entry may be negated by prefixing it with an exclamation mark
118
.Pq Sq !\& .
122
.Pq Sq !\& .
Lines 134-152 or Link Here
134
keyword) to be used only when the conditions following the
138
keyword) to be used only when the conditions following the
135
.Cm Match
139
.Cm Match
136
keyword are satisfied.
140
keyword are satisfied.
137
Match conditions are specified using one or more keyword/criteria pairs
141
Match conditions are specified using one or more critera
138
or the single token
142
or the single token
139
.Cm all
143
.Cm all
140
which matches all criteria.
144
which always matches.
141
The available keywords are:
145
The available criteria keywords are:
146
.Cm canonical ,
142
.Cm exec ,
147
.Cm exec ,
143
.Cm host ,
148
.Cm host ,
144
.Cm originalhost ,
149
.Cm originalhost ,
145
.Cm user ,
150
.Cm user ,
146
and
151
and
147
.Cm localuser .
152
.Cm localuser .
153
The
154
.Cm all
155
criteria must appear alone.
156
Other criteria may be combined arbitrarily.
157
All criteria but
158
.Cm all
159
and
160
.Cm canonical
161
require an argument.
148
.Pp
162
.Pp
149
The
163
The
164
.Cm canonical
165
keywork matches only when the configuration file is being re-parsed
166
after hostname canonicalization (see the
167
.Cm CanonicalizeHostname
168
option.)
169
This may be useful to specify conditions that work with canonical host
170
names only.
171
The
150
.Cm exec
172
.Cm exec
151
keyword executes the specified command under the user's shell.
173
keyword executes the specified command under the user's shell.
152
If the command returns a zero exit status then the condition is considered true.
174
If the command returns a zero exit status then the condition is considered true.
Lines 775-780 The default is the name given on the com Link Here
775
Numeric IP addresses are also permitted (both on the command line and in
797
Numeric IP addresses are also permitted (both on the command line and in
776
.Cm HostName
798
.Cm HostName
777
specifications).
799
specifications).
800
.Pp
801
If this option is enabled and results in the target hostname
802
changing, then the configuration files are processed again using the new
803
target name to pick up any new configuration in matching
804
.Cm Host
805
stanzas.
778
.It Cm IdentitiesOnly
806
.It Cm IdentitiesOnly
779
Specifies that
807
Specifies that
780
.Xr ssh 1
808
.Xr ssh 1

Return to bug 2267