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

Collapse All | Expand All

(-)readconf.c (-67 / +379 lines)
Lines 33-38 Link Here
33
#include <string.h>
33
#include <string.h>
34
#include <unistd.h>
34
#include <unistd.h>
35
#include <util.h>
35
#include <util.h>
36
#include <vis.h>
36
37
37
#include "xmalloc.h"
38
#include "xmalloc.h"
38
#include "ssh.h"
39
#include "ssh.h"
Lines 48-53 Link Here
48
#include "kex.h"
49
#include "kex.h"
49
#include "mac.h"
50
#include "mac.h"
50
#include "uidswap.h"
51
#include "uidswap.h"
52
#include "myproposal.h"
51
53
52
/* Format of the configuration file:
54
/* Format of the configuration file:
53
55
Lines 127-133 typedef enum { Link Here
127
	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
129
	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
128
	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
130
	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
129
	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
131
	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
130
	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
132
	oPubkeyAuthentication,
131
	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
133
	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
132
	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
134
	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
133
	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
135
	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
Lines 204-210 static struct { Link Here
204
	{ "globalknownhostsfile", oGlobalKnownHostsFile },
206
	{ "globalknownhostsfile", oGlobalKnownHostsFile },
205
	{ "globalknownhostsfile2", oDeprecated },
207
	{ "globalknownhostsfile2", oDeprecated },
206
	{ "userknownhostsfile", oUserKnownHostsFile },
208
	{ "userknownhostsfile", oUserKnownHostsFile },
207
	{ "userknownhostsfile2", oDeprecated }, 
209
	{ "userknownhostsfile2", oDeprecated },
208
	{ "connectionattempts", oConnectionAttempts },
210
	{ "connectionattempts", oConnectionAttempts },
209
	{ "batchmode", oBatchMode },
211
	{ "batchmode", oBatchMode },
210
	{ "checkhostip", oCheckHostIP },
212
	{ "checkhostip", oCheckHostIP },
Lines 457-463 execute_in_shell(const char *cmd) Link Here
457
	if (!WIFEXITED(status)) {
459
	if (!WIFEXITED(status)) {
458
		error("command '%.100s' exited abnormally", cmd);
460
		error("command '%.100s' exited abnormally", cmd);
459
		return -1;
461
		return -1;
460
	} 
462
	}
461
	debug3("command returned status %d", WEXITSTATUS(status));
463
	debug3("command returned status %d", WEXITSTATUS(status));
462
	return WEXITSTATUS(status);
464
	return WEXITSTATUS(status);
463
}
465
}
Lines 467-477 execute_in_shell(const char *cmd) Link Here
467
 */
469
 */
468
static int
470
static int
469
match_cfg_line(Options *options, char **condition, struct passwd *pw,
471
match_cfg_line(Options *options, char **condition, struct passwd *pw,
470
    const char *host_arg, const char *filename, int linenum)
472
    const char *host_arg, const char *original_host, int post_canon,
473
    const char *filename, int linenum)
471
{
474
{
472
	char *arg, *attrib, *cmd, *cp = *condition, *host;
475
	char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
473
	const char *ruser;
476
	const char *ruser;
474
	int r, port, result = 1, attributes = 0;
477
	int r, port, this_result, result = 1, attributes = 0, negate;
475
	size_t len;
478
	size_t len;
476
	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
479
	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
477
480
Lines 488-508 match_cfg_line(Options *options, char **condition, struct passwd *pw, Link Here
488
	} else
491
	} else
489
		host = xstrdup(host_arg);
492
		host = xstrdup(host_arg);
490
493
491
	debug3("checking match for '%s' host %s", cp, host);
494
	debug2("checking match for '%s' host %s originally %s",
492
	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
495
	    cp, host, original_host);
493
		attributes++;
496
	while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
497
		criteria = NULL;
498
		this_result = 1;
499
		if ((negate = attrib[0] == '!'))
500
			attrib++;
501
		/* criteria "all" and "canonical" have no argument */
494
		if (strcasecmp(attrib, "all") == 0) {
502
		if (strcasecmp(attrib, "all") == 0) {
495
			if (attributes != 1 ||
503
			if (attributes > 1 ||
496
			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
504
			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
497
				error("'all' cannot be combined with other "
505
				error("%.200s line %d: '%s' cannot be combined "
498
				    "Match attributes");
506
				    "with other Match attributes",
507
				    filename, linenum, oattrib);
499
				result = -1;
508
				result = -1;
500
				goto out;
509
				goto out;
501
			}
510
			}
502
			*condition = cp;
511
			if (result)
503
			result = 1;
512
				result = negate ? 0 : 1;
504
			goto out;
513
			goto out;
505
		}
514
		}
515
		attributes++;
516
		if (strcasecmp(attrib, "canonical") == 0) {
517
			r = !!post_canon;  /* force bitmask member to boolean */
518
			if (r == (negate ? 1 : 0))
519
				this_result = result = 0;
520
			debug3("%.200s line %d: %smatched '%s'",
521
			    filename, linenum,
522
			    this_result ? "" : "not ", oattrib);
523
			continue;
524
		}
525
		/* All other criteria require an argument */
506
		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
526
		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
507
			error("Missing Match criteria for %s", attrib);
527
			error("Missing Match criteria for %s", attrib);
508
			result = -1;
528
			result = -1;
Lines 510-540 match_cfg_line(Options *options, char **condition, struct passwd *pw, Link Here
510
		}
530
		}
511
		len = strlen(arg);
531
		len = strlen(arg);
512
		if (strcasecmp(attrib, "host") == 0) {
532
		if (strcasecmp(attrib, "host") == 0) {
513
			if (match_hostname(host, arg, len) != 1)
533
			criteria = xstrdup(host);
514
				result = 0;
534
			r = match_hostname(host, arg, len) == 1;
515
			else
535
			if (r == (negate ? 1 : 0))
516
				debug("%.200s line %d: matched 'Host %.100s' ",
536
				this_result = result = 0;
517
				    filename, linenum, host);
518
		} else if (strcasecmp(attrib, "originalhost") == 0) {
537
		} else if (strcasecmp(attrib, "originalhost") == 0) {
519
			if (match_hostname(host_arg, arg, len) != 1)
538
			criteria = xstrdup(original_host);
520
				result = 0;
539
			r = match_hostname(original_host, arg, len) == 1;
521
			else
540
			if (r == (negate ? 1 : 0))
522
				debug("%.200s line %d: matched "
541
				this_result = result = 0;
523
				    "'OriginalHost %.100s' ",
524
				    filename, linenum, host_arg);
525
		} else if (strcasecmp(attrib, "user") == 0) {
542
		} else if (strcasecmp(attrib, "user") == 0) {
526
			if (match_pattern_list(ruser, arg, len, 0) != 1)
543
			criteria = xstrdup(ruser);
527
				result = 0;
544
			r = match_pattern_list(ruser, arg, len, 0) == 1;
528
			else
545
			if (r == (negate ? 1 : 0))
529
				debug("%.200s line %d: matched 'User %.100s' ",
546
				this_result = result = 0;
530
				    filename, linenum, ruser);
531
		} else if (strcasecmp(attrib, "localuser") == 0) {
547
		} else if (strcasecmp(attrib, "localuser") == 0) {
532
			if (match_pattern_list(pw->pw_name, arg, len, 0) != 1)
548
			criteria = xstrdup(pw->pw_name);
533
				result = 0;
549
			r = match_pattern_list(pw->pw_name, arg, len, 0) == 1;
534
			else
550
			if (r == (negate ? 1 : 0))
535
				debug("%.200s line %d: matched "
551
				this_result = result = 0;
536
				    "'LocalUser %.100s' ",
537
				    filename, linenum, pw->pw_name);
538
		} else if (strcasecmp(attrib, "exec") == 0) {
552
		} else if (strcasecmp(attrib, "exec") == 0) {
539
			if (gethostname(thishost, sizeof(thishost)) == -1)
553
			if (gethostname(thishost, sizeof(thishost)) == -1)
540
				fatal("gethostname: %s", strerror(errno));
554
				fatal("gethostname: %s", strerror(errno));
Lines 547-593 match_cfg_line(Options *options, char **condition, struct passwd *pw, Link Here
547
			    "d", pw->pw_dir,
561
			    "d", pw->pw_dir,
548
			    "h", host,
562
			    "h", host,
549
			    "l", thishost,
563
			    "l", thishost,
550
			    "n", host_arg,
564
			    "n", original_host,
551
			    "p", portstr,
565
			    "p", portstr,
552
			    "r", ruser,
566
			    "r", ruser,
553
			    "u", pw->pw_name,
567
			    "u", pw->pw_name,
554
			    (char *)NULL);
568
			    (char *)NULL);
555
			if (result != 1) {
569
			if (result != 1) {
556
				/* skip execution if prior predicate failed */
570
				/* skip execution if prior predicate failed */
557
				debug("%.200s line %d: skipped exec \"%.100s\"",
571
				debug3("%.200s line %d: skipped exec "
558
				    filename, linenum, cmd);
572
				    "\"%.100s\"", filename, linenum, cmd);
559
			} else {
573
				free(cmd);
560
				r = execute_in_shell(cmd);
574
				continue;
561
				if (r == -1) {
562
					fatal("%.200s line %d: match exec "
563
					    "'%.100s' error", filename,
564
					    linenum, cmd);
565
				} else if (r == 0) {
566
					debug("%.200s line %d: matched "
567
					    "'exec \"%.100s\"'", filename,
568
					    linenum, cmd);
569
				} else {
570
					debug("%.200s line %d: no match "
571
					    "'exec \"%.100s\"'", filename,
572
					    linenum, cmd);
573
					result = 0;
574
				}
575
			}
575
			}
576
			r = execute_in_shell(cmd);
577
			if (r == -1) {
578
				fatal("%.200s line %d: match exec "
579
				    "'%.100s' error", filename,
580
				    linenum, cmd);
581
			}
582
			criteria = xstrdup(cmd);
576
			free(cmd);
583
			free(cmd);
584
			/* Force exit status to boolean */
585
			r = r == 0;
586
			if (r == (negate ? 1 : 0))
587
				this_result = result = 0;
577
		} else {
588
		} else {
578
			error("Unsupported Match attribute %s", attrib);
589
			error("Unsupported Match attribute %s", attrib);
579
			result = -1;
590
			result = -1;
580
			goto out;
591
			goto out;
581
		}
592
		}
593
		debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
594
		    filename, linenum, this_result ? "": "not ",
595
		    oattrib, criteria);
596
		free(criteria);
582
	}
597
	}
583
	if (attributes == 0) {
598
	if (attributes == 0) {
584
		error("One or more attributes required for Match");
599
		error("One or more attributes required for Match");
585
		result = -1;
600
		result = -1;
586
		goto out;
601
		goto out;
587
	}
602
	}
588
	debug3("match %sfound", result ? "" : "not ");
589
	*condition = cp;
590
 out:
603
 out:
604
	if (result != -1)
605
		debug2("match %sfound", result ? "" : "not ");
606
	*condition = cp;
591
	free(host);
607
	free(host);
592
	return result;
608
	return result;
593
}
609
}
Lines 710-716 static const struct multistate multistate_canonicalizehostname[] = { Link Here
710
#define WHITESPACE " \t\r\n"
726
#define WHITESPACE " \t\r\n"
711
int
727
int
712
process_config_line(Options *options, struct passwd *pw, const char *host,
728
process_config_line(Options *options, struct passwd *pw, const char *host,
713
    char *line, const char *filename, int linenum, int *activep, int userconfig)
729
    const char *original_host, char *line, const char *filename,
730
    int linenum, int *activep, int flags)
714
{
731
{
715
	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
732
	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
716
	char **cpptr, fwdarg[256];
733
	char **cpptr, fwdarg[256];
Lines 766-772 parse_time: Link Here
766
		if (!arg || *arg == '\0')
783
		if (!arg || *arg == '\0')
767
			fatal("%s line %d: missing time value.",
784
			fatal("%s line %d: missing time value.",
768
			    filename, linenum);
785
			    filename, linenum);
769
		if ((value = convtime(arg)) == -1)
786
		if (strcmp(arg, "none") == 0)
787
			value = -1;
788
		else if ((value = convtime(arg)) == -1)
770
			fatal("%s line %d: invalid time value.",
789
			fatal("%s line %d: invalid time value.",
771
			    filename, linenum);
790
			    filename, linenum);
772
		if (*activep && *intptr == -1)
791
		if (*activep && *intptr == -1)
Lines 803-809 parse_time: Link Here
803
	case oForwardX11Trusted:
822
	case oForwardX11Trusted:
804
		intptr = &options->forward_x11_trusted;
823
		intptr = &options->forward_x11_trusted;
805
		goto parse_flag;
824
		goto parse_flag;
806
	
825
807
	case oForwardX11Timeout:
826
	case oForwardX11Timeout:
808
		intptr = &options->forward_x11_timeout;
827
		intptr = &options->forward_x11_timeout;
809
		goto parse_time;
828
		goto parse_time;
Lines 938-944 parse_time: Link Here
938
			if (*intptr >= SSH_MAX_IDENTITY_FILES)
957
			if (*intptr >= SSH_MAX_IDENTITY_FILES)
939
				fatal("%.200s line %d: Too many identity files specified (max %d).",
958
				fatal("%.200s line %d: Too many identity files specified (max %d).",
940
				    filename, linenum, SSH_MAX_IDENTITY_FILES);
959
				    filename, linenum, SSH_MAX_IDENTITY_FILES);
941
			add_identity_file(options, NULL, arg, userconfig);
960
			add_identity_file(options, NULL,
961
			    arg, flags & SSHCONF_USERCONF);
942
		}
962
		}
943
		break;
963
		break;
944
964
Lines 1186-1193 parse_int: Link Here
1186
		if (cmdline)
1206
		if (cmdline)
1187
			fatal("Host directive not supported as a command-line "
1207
			fatal("Host directive not supported as a command-line "
1188
			    "option");
1208
			    "option");
1189
		value = match_cfg_line(options, &s, pw, host,
1209
		value = match_cfg_line(options, &s, pw, host, original_host,
1190
		    filename, linenum);
1210
		    flags & SSHCONF_POSTCANON, filename, linenum);
1191
		if (value < 0)
1211
		if (value < 0)
1192
			fatal("%.200s line %d: Bad Match condition", filename,
1212
			fatal("%.200s line %d: Bad Match condition", filename,
1193
			    linenum);
1213
			    linenum);
Lines 1435-1441 parse_int: Link Here
1435
		return 0;
1455
		return 0;
1436
1456
1437
	default:
1457
	default:
1438
		fatal("process_config_line: Unimplemented opcode %d", opcode);
1458
		fatal("%s: Unimplemented opcode %d", __func__, opcode);
1439
	}
1459
	}
1440
1460
1441
	/* Check that there is no garbage at end of line. */
1461
	/* Check that there is no garbage at end of line. */
Lines 1455-1461 parse_int: Link Here
1455
1475
1456
int
1476
int
1457
read_config_file(const char *filename, struct passwd *pw, const char *host,
1477
read_config_file(const char *filename, struct passwd *pw, const char *host,
1458
    Options *options, int flags)
1478
    const char *original_host, Options *options, int flags)
1459
{
1479
{
1460
	FILE *f;
1480
	FILE *f;
1461
	char line[1024];
1481
	char line[1024];
Lines 1486-1493 read_config_file(const char *filename, struct passwd *pw, const char *host, Link Here
1486
	while (fgets(line, sizeof(line), f)) {
1506
	while (fgets(line, sizeof(line), f)) {
1487
		/* Update line number counter. */
1507
		/* Update line number counter. */
1488
		linenum++;
1508
		linenum++;
1489
		if (process_config_line(options, pw, host, line, filename,
1509
		if (process_config_line(options, pw, host, original_host,
1490
		    linenum, &active, flags & SSHCONF_USERCONF) != 0)
1510
		    line, filename, linenum, &active, flags) != 0)
1491
			bad_options++;
1511
			bad_options++;
1492
	}
1512
	}
1493
	fclose(f);
1513
	fclose(f);
Lines 1998-2000 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remo Link Here
1998
	fwd->listen_path = NULL;
2018
	fwd->listen_path = NULL;
1999
	return (0);
2019
	return (0);
2000
}
2020
}
2021
2022
/* XXX the following is a near-vebatim copy from servconf.c; refactor */
2023
static const char *
2024
fmt_multistate_int(int val, const struct multistate *m)
2025
{
2026
	u_int i;
2027
2028
	for (i = 0; m[i].key != NULL; i++) {
2029
		if (m[i].value == val)
2030
			return m[i].key;
2031
	}
2032
	return "UNKNOWN";
2033
}
2034
2035
static const char *
2036
fmt_intarg(OpCodes code, int val)
2037
{
2038
	if (val == -1)
2039
		return "unset";
2040
	switch (code) {
2041
	case oAddressFamily:
2042
		return fmt_multistate_int(val, multistate_addressfamily);
2043
	case oVerifyHostKeyDNS:
2044
	case oStrictHostKeyChecking:
2045
		return fmt_multistate_int(val, multistate_yesnoask);
2046
	case oControlMaster:
2047
		return fmt_multistate_int(val, multistate_controlmaster);
2048
	case oTunnel:
2049
		return fmt_multistate_int(val, multistate_tunnel);
2050
	case oRequestTTY:
2051
		return fmt_multistate_int(val, multistate_requesttty);
2052
	case oCanonicalizeHostname:
2053
		return fmt_multistate_int(val, multistate_canonicalizehostname);
2054
	case oProtocol:
2055
		switch (val) {
2056
		case SSH_PROTO_1:
2057
			return "1";
2058
		case SSH_PROTO_2:
2059
			return "2";
2060
		case (SSH_PROTO_1|SSH_PROTO_2):
2061
			return "2,1";
2062
		default:
2063
			return "UNKNOWN";
2064
		}
2065
	default:
2066
		switch (val) {
2067
		case 0:
2068
			return "no";
2069
		case 1:
2070
			return "yes";
2071
		default:
2072
			return "UNKNOWN";
2073
		}
2074
	}
2075
}
2076
2077
static const char *
2078
lookup_opcode_name(OpCodes code)
2079
{
2080
	u_int i;
2081
2082
	for (i = 0; keywords[i].name != NULL; i++)
2083
		if (keywords[i].opcode == code)
2084
			return(keywords[i].name);
2085
	return "UNKNOWN";
2086
}
2087
2088
static void
2089
dump_cfg_int(OpCodes code, int val)
2090
{
2091
	printf("%s %d\n", lookup_opcode_name(code), val);
2092
}
2093
2094
static void
2095
dump_cfg_fmtint(OpCodes code, int val)
2096
{
2097
	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2098
}
2099
2100
static void
2101
dump_cfg_string(OpCodes code, const char *val)
2102
{
2103
	if (val == NULL)
2104
		return;
2105
	printf("%s %s\n", lookup_opcode_name(code), val);
2106
}
2107
2108
static void
2109
dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2110
{
2111
	u_int i;
2112
2113
	for (i = 0; i < count; i++)
2114
		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2115
}
2116
2117
static void
2118
dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2119
{
2120
	u_int i;
2121
2122
	printf("%s", lookup_opcode_name(code));
2123
	for (i = 0; i < count; i++)
2124
		printf(" %s",  vals[i]);
2125
	printf("\n");
2126
}
2127
2128
static void
2129
dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2130
{
2131
	const struct Forward *fwd;
2132
	u_int i;
2133
2134
	/* oDynamicForward */
2135
	for (i = 0; i < count; i++) {
2136
		fwd = &fwds[i];
2137
		if (code == oDynamicForward &&
2138
		    strcmp(fwd->connect_host, "socks") != 0)
2139
			continue;
2140
		if (code == oLocalForward &&
2141
		    strcmp(fwd->connect_host, "socks") == 0)
2142
			continue;
2143
		printf("%s", lookup_opcode_name(code));
2144
		if (fwd->listen_port == PORT_STREAMLOCAL)
2145
			printf(" %s", fwd->listen_path);
2146
		else if (fwd->listen_host == NULL)
2147
			printf(" %d", fwd->listen_port);
2148
		else {
2149
			printf(" [%s]:%d",
2150
			    fwd->listen_host, fwd->listen_port);
2151
		}
2152
		if (code != oDynamicForward) {
2153
			if (fwd->connect_port == PORT_STREAMLOCAL)
2154
				printf(" %s", fwd->connect_path);
2155
			else if (fwd->connect_host == NULL)
2156
				printf(" %d", fwd->connect_port);
2157
			else {
2158
				printf(" [%s]:%d",
2159
				    fwd->connect_host, fwd->connect_port);
2160
			}
2161
		}
2162
		printf("\n");
2163
	}
2164
}
2165
2166
void
2167
dump_client_config(Options *o, const char *host)
2168
{
2169
	int i;
2170
	char vbuf[5];
2171
2172
	/* Most interesting options first: user, host, port */
2173
	dump_cfg_string(oUser, o->user);
2174
	dump_cfg_string(oHostName, host);
2175
	dump_cfg_int(oPort, o->port);
2176
2177
	/* Flag options */
2178
	dump_cfg_fmtint(oAddressFamily, o->address_family);
2179
	dump_cfg_fmtint(oBatchMode, o->batch_mode);
2180
	dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2181
	dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2182
	dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2183
	dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2184
	dump_cfg_fmtint(oCompression, o->compression);
2185
	dump_cfg_fmtint(oControlMaster, o->control_master);
2186
	dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2187
	dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2188
	dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2189
	dump_cfg_fmtint(oForwardX11, o->forward_x11);
2190
	dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2191
	dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2192
#ifdef GSSAPI
2193
	dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2194
	dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2195
#endif /* GSSAPI */
2196
	dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2197
	dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2198
	dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2199
	dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2200
	dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2201
	dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2202
	dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2203
	dump_cfg_fmtint(oProtocol, o->protocol);
2204
	dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2205
	dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2206
	dump_cfg_fmtint(oRequestTTY, o->request_tty);
2207
	dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2208
	dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2209
	dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2210
	dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2211
	dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2212
	dump_cfg_fmtint(oTunnel, o->tun_open);
2213
	dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2214
	dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2215
	dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2216
2217
	/* Integer options */
2218
	dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2219
	dump_cfg_int(oCompressionLevel, o->compression_level);
2220
	dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2221
	dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2222
	dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2223
	dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2224
	dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2225
2226
	/* String options */
2227
	dump_cfg_string(oBindAddress, o->bind_address);
2228
	dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2229
	dump_cfg_string(oControlPath, o->control_path);
2230
	dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2231
	dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2232
	dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2233
	dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2234
	dump_cfg_string(oLocalCommand, o->local_command);
2235
	dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2236
	dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2237
	dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2238
	dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2239
	dump_cfg_string(oProxyCommand, o->proxy_command);
2240
	dump_cfg_string(oXAuthLocation, o->xauth_location);
2241
2242
	dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2243
	dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2244
	dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2245
2246
	/* String array options */
2247
	dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2248
	dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2249
	dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2250
	dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2251
	dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2252
2253
	/* Special cases */
2254
2255
	/* oConnectTimeout */
2256
	if (o->connection_timeout == -1)
2257
		printf("connecttimeout none\n");
2258
	else
2259
		dump_cfg_int(oConnectTimeout, o->connection_timeout);
2260
2261
	/* oTunnelDevice */
2262
	printf("tunneldevice");
2263
	if (o->tun_local == SSH_TUNID_ANY)
2264
		printf(" any");
2265
	else
2266
		printf(" %d", o->tun_local);
2267
	if (o->tun_remote == SSH_TUNID_ANY)
2268
		printf(":any");
2269
	else
2270
		printf(":%d", o->tun_remote);
2271
	printf("\n");
2272
2273
	/* oCanonicalizePermittedCNAMEs */
2274
	if ( o->num_permitted_cnames > 0) {
2275
		printf("canonicalizePermittedcnames");
2276
		for (i = 0; i < o->num_permitted_cnames; i++) {
2277
			printf(" %s:%s", o->permitted_cnames[i].source_list,
2278
			    o->permitted_cnames[i].target_list);
2279
		}
2280
		printf("\n");
2281
	}
2282
2283
	/* oCipher */
2284
	if (o->cipher != SSH_CIPHER_NOT_SET)
2285
		printf("Cipher %s\n", cipher_name(o->cipher));
2286
2287
	/* oControlPersist */
2288
	if (o->control_persist == 0 || o->control_persist_timeout == 0)
2289
		dump_cfg_fmtint(oControlPersist, o->control_persist);
2290
	else
2291
		dump_cfg_int(oControlPersist, o->control_persist_timeout);
2292
2293
	/* oEscapeChar */
2294
	if (o->escape_char == SSH_ESCAPECHAR_NONE)
2295
		printf("escapechar none\n");
2296
	else {
2297
		vis(vbuf, o->escape_char, VIS_WHITE, 0);
2298
		printf("escapechar %s\n", vbuf);
2299
	}
2300
2301
	/* oIPQoS */
2302
	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2303
	printf("%s\n", iptos2str(o->ip_qos_bulk));
2304
2305
	/* oRekeyLimit */
2306
	printf("rekeylimit %lld %d\n",
2307
	    (long long)o->rekey_limit, o->rekey_interval);
2308
2309
	/* oStreamLocalBindMask */
2310
	printf("streamlocalbindmask 0%o\n",
2311
	    o->fwd_opts.streamlocal_bind_mask);
2312
}
(-)readconf.h (-3 / +5 lines)
Lines 164-180 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 *);
179
void	 dump_client_config(Options *o, const char *host);
178
180
179
void	 add_local_forward(Options *, const struct Forward *);
181
void	 add_local_forward(Options *, const struct Forward *);
180
void	 add_remote_forward(Options *, const struct Forward *);
182
void	 add_remote_forward(Options *, const struct Forward *);
(-)ssh-keysign.c (-1 / +1 lines)
Lines 178-184 main(int argc, char **argv) Link Here
178
178
179
	/* verify that ssh-keysign is enabled by the admin */
179
	/* verify that ssh-keysign is enabled by the admin */
180
	initialize_options(&options);
180
	initialize_options(&options);
181
	(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", &options, 0);
181
	(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", &options, 0);
182
	fill_default_options(&options);
182
	fill_default_options(&options);
183
	if (options.enable_ssh_keysign != 1)
183
	if (options.enable_ssh_keysign != 1)
184
		fatal("ssh-keysign not enabled in %s",
184
		fatal("ssh-keysign not enabled in %s",
(-)ssh.1 (-1 / +9 lines)
Lines 43-49 Link Here
43
.Sh SYNOPSIS
43
.Sh SYNOPSIS
44
.Nm ssh
44
.Nm ssh
45
.Bk -words
45
.Bk -words
46
.Op Fl 1246AaCfgKkMNnqsTtVvXxYy
46
.Op Fl 1246AaCfgGKkMNnqsTtVvXxYy
47
.Op Fl b Ar bind_address
47
.Op Fl b Ar bind_address
48
.Op Fl c Ar cipher_spec
48
.Op Fl c Ar cipher_spec
49
.Op Fl D Oo Ar bind_address : Oc Ns Ar port
49
.Op Fl D Oo Ar bind_address : Oc Ns Ar port
Lines 251-256 then a client started with Link Here
251
.Fl f
251
.Fl f
252
will wait for all remote port forwards to be successfully established
252
will wait for all remote port forwards to be successfully established
253
before placing itself in the background.
253
before placing itself in the background.
254
.It Fl G
255
Causes
256
.Nm
257
to print its configuration after evaluating
258
.Cm Host
259
and
260
.Cm Match
261
blocks and exit.
254
.It Fl g
262
.It Fl g
255
Allows remote hosts to connect to local forwarded ports.
263
Allows remote hosts to connect to local forwarded ports.
256
If used on a multiplexed connection, then this option must be specified
264
If used on a multiplexed connection, then this option must be specified
(-)ssh.c (-20 / +30 lines)
Lines 370-396 resolve_canonicalize(char **hostp, int port) Link Here
370
 * file if the user specifies a config file on the command line.
370
 * file if the user specifies a config file on the command line.
371
 */
371
 */
372
static void
372
static void
373
process_config_files(struct passwd *pw)
373
process_config_files(const char *host_arg, struct passwd *pw, int post_canon)
374
{
374
{
375
	char buf[MAXPATHLEN];
375
	char buf[MAXPATHLEN];
376
	int r;
376
	int r;
377
377
378
	if (config != NULL) {
378
	if (config != NULL) {
379
		if (strcasecmp(config, "none") != 0 &&
379
		if (strcasecmp(config, "none") != 0 &&
380
		    !read_config_file(config, pw, host, &options,
380
		    !read_config_file(config, pw, host, host_arg, &options,
381
		    SSHCONF_USERCONF))
381
		    SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)))
382
			fatal("Can't open user config file %.100s: "
382
			fatal("Can't open user config file %.100s: "
383
			    "%.100s", config, strerror(errno));
383
			    "%.100s", config, strerror(errno));
384
	} else {
384
	} else {
385
		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
385
		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
386
		    _PATH_SSH_USER_CONFFILE);
386
		    _PATH_SSH_USER_CONFFILE);
387
		if (r > 0 && (size_t)r < sizeof(buf))
387
		if (r > 0 && (size_t)r < sizeof(buf))
388
			(void)read_config_file(buf, pw, host, &options,
388
			(void)read_config_file(buf, pw, host, host_arg,
389
			     SSHCONF_CHECKPERM|SSHCONF_USERCONF);
389
			    &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |
390
			    (post_canon ? SSHCONF_POSTCANON : 0));
390
391
391
		/* Read systemwide configuration file after user config. */
392
		/* Read systemwide configuration file after user config. */
392
		(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host,
393
		(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
393
		    &options, 0);
394
		    host, host_arg, &options,
395
		    post_canon ? SSHCONF_POSTCANON : 0);
394
	}
396
	}
395
}
397
}
396
398
Lines 400-406 process_config_files(struct passwd *pw) Link Here
400
int
402
int
401
main(int ac, char **av)
403
main(int ac, char **av)
402
{
404
{
403
	int i, r, opt, exit_status, use_syslog;
405
	int i, r, opt, exit_status, use_syslog, config_test = 0;
404
	char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile;
406
	char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile;
405
	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
407
	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
406
	char cname[NI_MAXHOST];
408
	char cname[NI_MAXHOST];
Lines 478-484 main(int ac, char **av) Link Here
478
480
479
 again:
481
 again:
480
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
482
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
481
	    "ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
483
	    "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
482
		switch (opt) {
484
		switch (opt) {
483
		case '1':
485
		case '1':
484
			options.protocol = SSH_PROTO_1;
486
			options.protocol = SSH_PROTO_1;
Lines 511-516 main(int ac, char **av) Link Here
511
		case 'E':
513
		case 'E':
512
			logfile = xstrdup(optarg);
514
			logfile = xstrdup(optarg);
513
			break;
515
			break;
516
		case 'G':
517
			config_test = 1;
518
			break;
514
		case 'Y':
519
		case 'Y':
515
			options.forward_x11 = 1;
520
			options.forward_x11 = 1;
516
			options.forward_x11_trusted = 1;
521
			options.forward_x11_trusted = 1;
Lines 759-767 main(int ac, char **av) Link Here
759
			break;
764
			break;
760
		case 'o':
765
		case 'o':
761
			line = xstrdup(optarg);
766
			line = xstrdup(optarg);
762
			if (process_config_line(&options, pw, host ? host : "",
767
			if (process_config_line(&options, pw,
763
			    line, "command-line", 0, NULL, SSHCONF_USERCONF)
768
			    host ? host : "", host ? host : "", line,
764
			    != 0)
769
			    "command-line", 0, NULL, SSHCONF_USERCONF) != 0)
765
				exit(255);
770
				exit(255);
766
			free(line);
771
			free(line);
767
			break;
772
			break;
Lines 870-876 main(int ac, char **av) Link Here
870
		);
875
		);
871
876
872
	/* Parse the configuration files */
877
	/* Parse the configuration files */
873
	process_config_files(pw);
878
	process_config_files(host_arg, pw, 0);
874
879
875
	/* Hostname canonicalisation needs a few options filled. */
880
	/* Hostname canonicalisation needs a few options filled. */
876
	fill_default_options_for_canonicalization(&options);
881
	fill_default_options_for_canonicalization(&options);
Lines 882-887 main(int ac, char **av) Link Here
882
		    "h", host, (char *)NULL);
887
		    "h", host, (char *)NULL);
883
		free(host);
888
		free(host);
884
		host = cp;
889
		host = cp;
890
		free(options.hostname);
891
		options.hostname = xstrdup(host);
885
	}
892
	}
886
893
887
	/* If canonicalization requested then try to apply it */
894
	/* If canonicalization requested then try to apply it */
Lines 915-927 main(int ac, char **av) Link Here
915
			check_follow_cname(&host, cname);
922
			check_follow_cname(&host, cname);
916
	}
923
	}
917
924
918
	/*
925
	if (options.canonicalize_hostname != 0) {
919
	 * If the target hostname has changed as a result of canonicalisation
926
		debug("Re-reading configuration");
920
	 * then re-parse the configuration files as new stanzas may match.
927
		free(options.hostname);
921
	 */
928
		options.hostname = xstrdup(host);
922
	if (strcasecmp(host_arg, host) != 0) {
929
		process_config_files(host_arg, pw, 1);
923
		debug("Hostname has changed; re-reading configuration");
924
		process_config_files(pw);
925
	}
930
	}
926
931
927
	/* Fill configuration defaults. */
932
	/* Fill configuration defaults. */
Lines 1019-1024 main(int ac, char **av) Link Here
1019
	}
1024
	}
1020
	free(conn_hash_hex);
1025
	free(conn_hash_hex);
1021
1026
1027
	if (config_test) {
1028
		dump_client_config(&options, host);
1029
		exit(0);
1030
	}
1031
1022
	if (muxclient_command != 0 && options.control_path == NULL)
1032
	if (muxclient_command != 0 && options.control_path == NULL)
1023
		fatal("No ControlPath specified for \"-O\" command");
1033
		fatal("No ControlPath specified for \"-O\" command");
1024
	if (options.control_path != NULL)
1034
	if (options.control_path != NULL)
(-)ssh_config.5 (-11 / +46 lines)
Lines 65-71 The configuration files contain sections separated by 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 usually the one given on the command line
69
(see the
70
.Cm CanonicalizeHostname
71
option for exceptions.)
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 109-118 A single Link Here
109
.Ql *
112
.Ql *
110
as a pattern can be used to provide global
113
as a pattern can be used to provide global
111
defaults for all hosts.
114
defaults for all hosts.
112
The host is the
115
The host is usually 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
115
a canonicalized host name before matching).
118
(see the
119
.Cm CanonicalizeHostname
120
option for exceptions.)
116
.Pp
121
.Pp
117
A pattern entry may be negated by prefixing it with an exclamation mark
122
A pattern entry may be negated by prefixing it with an exclamation mark
118
.Pq Sq !\& .
123
.Pq Sq !\& .
Lines 134-152 or Link Here
134
keyword) to be used only when the conditions following the
139
keyword) to be used only when the conditions following the
135
.Cm Match
140
.Cm Match
136
keyword are satisfied.
141
keyword are satisfied.
137
Match conditions are specified using one or more keyword/criteria pairs
142
Match conditions are specified using one or more critera
138
or the single token
143
or the single token
139
.Cm all
144
.Cm all
140
which matches all criteria.
145
which always matches.
141
The available keywords are:
146
The available criteria keywords are:
147
.Cm canonical ,
142
.Cm exec ,
148
.Cm exec ,
143
.Cm host ,
149
.Cm host ,
144
.Cm originalhost ,
150
.Cm originalhost ,
145
.Cm user ,
151
.Cm user ,
146
and
152
and
147
.Cm localuser .
153
.Cm localuser .
154
The
155
.Cm all
156
criteria must appear alone or immediately after
157
.Cm canonical.
158
Other criteria may be combined arbitrarily.
159
All criteria but
160
.Cm all
161
and
162
.Cm canonical
163
require an argument.
164
Criteria may be negated by prepending an exclamation mark
165
.Pq Sq !\& .
148
.Pp
166
.Pp
149
The
167
The
168
.Cm canonical
169
keywork matches only when the configuration file is being re-parsed
170
after hostname canonicalization (see the
171
.Cm CanonicalizeHostname
172
option.)
173
This may be useful to specify conditions that work with canonical host
174
names only.
175
The
150
.Cm exec
176
.Cm exec
151
keyword executes the specified command under the user's shell.
177
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.
178
If the command returns a zero exit status then the condition is considered true.
Lines 179-185 The criteria for the Link Here
179
keyword are matched against the target hostname, after any substitution
205
keyword are matched against the target hostname, after any substitution
180
by the
206
by the
181
.Cm Hostname
207
.Cm Hostname
182
option.
208
or
209
.Cm CanonicalizeHostname
210
options.
183
The
211
The
184
.Cm originalhost
212
.Cm originalhost
185
keyword matches against the hostname as it was specified on the command-line.
213
keyword matches against the hostname as it was specified on the command-line.
Lines 264-273 is set to Link Here
264
.Dq always ,
292
.Dq always ,
265
then canonicalization is applied to proxied connections too.
293
then canonicalization is applied to proxied connections too.
266
.Pp
294
.Pp
267
If this option is enabled and canonicalisation results in the target hostname
295
If this option is enabled, then the configuration files are processed
268
changing, then the configuration files are processed again using the new
296
again using the new target name to pick up any new configuration in matching
269
target name to pick up any new configuration in matching
270
.Cm Host
297
.Cm Host
298
and
299
.Cm Match
271
stanzas.
300
stanzas.
272
.It Cm CanonicalizeMaxDots
301
.It Cm CanonicalizeMaxDots
273
Specifies the maximum number of dot characters in a hostname before
302
Specifies the maximum number of dot characters in a hostname before
Lines 775-780 The default is the name given on the command line. Link Here
775
Numeric IP addresses are also permitted (both on the command line and in
804
Numeric IP addresses are also permitted (both on the command line and in
776
.Cm HostName
805
.Cm HostName
777
specifications).
806
specifications).
807
.Pp
808
If this option is enabled and results in the target hostname
809
changing, then the configuration files are processed again using the new
810
target name to pick up any new configuration in matching
811
.Cm Host
812
stanzas.
778
.It Cm IdentitiesOnly
813
.It Cm IdentitiesOnly
779
Specifies that
814
Specifies that
780
.Xr ssh 1
815
.Xr ssh 1

Return to bug 2267