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

Collapse All | Expand All

(-)a/addrmatch.c (-3 / +17 lines)
Lines 379-385 addr_match_list(const char *addr, const char *_list) Link Here
379
	char *list, *cp, *o;
379
	char *list, *cp, *o;
380
	struct xaddr try_addr, match_addr;
380
	struct xaddr try_addr, match_addr;
381
	u_int masklen, neg;
381
	u_int masklen, neg;
382
	int ret = 0, r;
382
	int got_neg = 0, seen_pos = 0, ret = 0, r;
383
383
384
	if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
384
	if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
385
		debug2("%s: couldn't parse address %.100s", __func__, addr);
385
		debug2("%s: couldn't parse address %.100s", __func__, addr);
Lines 391-396 addr_match_list(const char *addr, const char *_list) Link Here
391
		neg = *cp == '!';
391
		neg = *cp == '!';
392
		if (neg)
392
		if (neg)
393
			cp++;
393
			cp++;
394
		else
395
			seen_pos = 1;
394
		if (*cp == '\0') {
396
		if (*cp == '\0') {
395
			ret = -2;
397
			ret = -2;
396
			break;
398
			break;
Lines 411-426 addr_match_list(const char *addr, const char *_list) Link Here
411
					break;
413
					break;
412
				}
414
				}
413
				ret = 1;
415
				ret = 1;
414
			}
416
			} else if (neg)
417
				got_neg = 1;
415
			continue;
418
			continue;
416
		} else {
419
		} else {
417
			/* If CIDR parse failed, try wildcard string match */
420
			/* If CIDR parse failed, try wildcard string match */
418
			if (addr != NULL && match_pattern(addr, cp) == 1)
421
			if (addr == NULL)
422
				continue;
423
			if (match_pattern(addr, cp) == 1)
419
				goto foundit;
424
				goto foundit;
425
			else if (neg)
426
				got_neg = 1;
420
		}
427
		}
421
	}
428
	}
422
	free(o);
429
	free(o);
423
430
431
	/*
432
	 * Allow a list of all-negated clauses to return a positive result
433
	 * See the explanation in match_pattern_list() for more detail.
434
	 */
435
	if (ret == 0 && got_neg && !seen_pos)
436
		return 1;
437
424
	return ret;
438
	return ret;
425
}
439
}
426
440
(-)a/match.c (-4 / +21 lines)
Lines 122-138 match_pattern_list(const char *string, const char *pattern, int dolower) Link Here
122
{
122
{
123
	char sub[1024];
123
	char sub[1024];
124
	int negated;
124
	int negated;
125
	int got_positive;
125
	int got_positive, got_negative, seen_positive;
126
	u_int i, subi, len = strlen(pattern);
126
	u_int i, subi, len = strlen(pattern);
127
127
128
	got_positive = 0;
128
	seen_positive = got_positive = got_negative = 0;
129
	for (i = 0; i < len;) {
129
	for (i = 0; i < len;) {
130
		/* Check if the subpattern is negated. */
130
		/* Check if the subpattern is negated. */
131
		if (pattern[i] == '!') {
131
		if (pattern[i] == '!') {
132
			negated = 1;
132
			negated = 1;
133
			i++;
133
			i++;
134
		} else
134
		} else {
135
			negated = 0;
135
			negated = 0;
136
			seen_positive = 1;
137
		}
136
138
137
		/*
139
		/*
138
		 * Extract the subpattern up to a comma or end.  Convert the
140
		 * Extract the subpattern up to a comma or end.  Convert the
Lines 160-168 match_pattern_list(const char *string, const char *pattern, int dolower) Link Here
160
				return -1;		/* Negative */
162
				return -1;		/* Negative */
161
			else
163
			else
162
				got_positive = 1;	/* Positive */
164
				got_positive = 1;	/* Positive */
163
		}
165
		} else if (negated)
166
			got_negative = 1;
164
	}
167
	}
165
168
169
	/*
170
	 * Return success if we saw a negated match but only if all other
171
	 * patterns were negated too. E.g. matching "a" against a
172
	 * pattern-list "!b,!c,!d" should return 1.
173
	 *
174
	 * This avoids surprises with mixtures of negated and non-negated
175
	 * patterns. For example, given a pattern-list of of "!foo.xx,*.xx":
176
	 *     bar.xx => true
177
	 *     foo.xx => false
178
	 *     foo.yy => false
179
	 */
180
	if (got_negative && !seen_positive)
181
		return 1;
182
166
	/*
183
	/*
167
	 * Return success if got a positive match.  If there was a negative
184
	 * Return success if got a positive match.  If there was a negative
168
	 * match, we have already returned -1 and never get here.
185
	 * match, we have already returned -1 and never get here.
(-)a/regress/unittests/match/tests.c (-6 / +44 lines)
Lines 59-65 tests(void) Link Here
59
	ASSERT_INT_EQ(match_pattern_list("a", "*", 0), 1);
59
	ASSERT_INT_EQ(match_pattern_list("a", "*", 0), 1);
60
	ASSERT_INT_EQ(match_pattern_list("a", "!*", 0), -1);
60
	ASSERT_INT_EQ(match_pattern_list("a", "!*", 0), -1);
61
	ASSERT_INT_EQ(match_pattern_list("a", "!a", 0), -1);
61
	ASSERT_INT_EQ(match_pattern_list("a", "!a", 0), -1);
62
	/* XXX negated ASSERT_INT_EQ(match_pattern_list("a", "!b", 0), 1); */
62
	ASSERT_INT_EQ(match_pattern_list("a", "!a,!b", 0), -1);
63
	ASSERT_INT_EQ(match_pattern_list("a", "!b,!a", 0), -1);
64
	ASSERT_INT_EQ(match_pattern_list("a", "!b,!c", 0), 1);
63
	ASSERT_INT_EQ(match_pattern_list("a", "!a,*", 0), -1);
65
	ASSERT_INT_EQ(match_pattern_list("a", "!a,*", 0), -1);
64
	ASSERT_INT_EQ(match_pattern_list("b", "!a,*", 0), 1);
66
	ASSERT_INT_EQ(match_pattern_list("b", "!a,*", 0), 1);
65
	ASSERT_INT_EQ(match_pattern_list("a", "*,!a", 0), -1);
67
	ASSERT_INT_EQ(match_pattern_list("a", "*,!a", 0), -1);
Lines 67-73 tests(void) Link Here
67
	ASSERT_INT_EQ(match_pattern_list("a", "a,!*", 0), -1);
69
	ASSERT_INT_EQ(match_pattern_list("a", "a,!*", 0), -1);
68
	ASSERT_INT_EQ(match_pattern_list("b", "a,!*", 0), -1);
70
	ASSERT_INT_EQ(match_pattern_list("b", "a,!*", 0), -1);
69
	ASSERT_INT_EQ(match_pattern_list("a", "a,!a", 0), -1);
71
	ASSERT_INT_EQ(match_pattern_list("a", "a,!a", 0), -1);
70
	/* XXX negated ASSERT_INT_EQ(match_pattern_list("b", "a,!a", 0), 1); */
72
	ASSERT_INT_EQ(match_pattern_list("a.x", "!a.x,*.x", 0), -1);
73
	ASSERT_INT_EQ(match_pattern_list("a.x", "*.x,!a.x", 0), -1);
74
	ASSERT_INT_EQ(match_pattern_list("b.x", "!a.x,*.x", 0), 1);
75
	ASSERT_INT_EQ(match_pattern_list("b.x", "*.x,!a.x", 0), 1);
71
	ASSERT_INT_EQ(match_pattern_list("a", "!*,a", 0), -1);
76
	ASSERT_INT_EQ(match_pattern_list("a", "!*,a", 0), -1);
72
	ASSERT_INT_EQ(match_pattern_list("b", "!*,a", 0), -1);
77
	ASSERT_INT_EQ(match_pattern_list("b", "!*,a", 0), -1);
73
	TEST_DONE();
78
	TEST_DONE();
Lines 88-106 tests(void) Link Here
88
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.1"), 1);
93
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.1"), 1);
89
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.2"), 0);
94
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.2"), 0);
90
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.1"), -1);
95
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.1"), -1);
91
	/* XXX negated ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.2"), 1); */
96
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.2"), 1);
97
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.2,!127.0.0.3"), 1);
92
	ASSERT_INT_EQ(addr_match_list("127.0.0.255", "127.0.0.0/24"), 1);
98
	ASSERT_INT_EQ(addr_match_list("127.0.0.255", "127.0.0.0/24"), 1);
93
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "127.0.0.0/24"), 0);
99
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "127.0.0.0/24"), 0);
94
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.0/24"), 1);
100
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.0/24"), 1);
95
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.1.0/24"), 0);
101
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.1.0/24"), 0);
96
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.0/24"), -1);
102
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.0/24"), -1);
97
	/* XXX negated ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.1.0/24"), 1); */
103
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.1.0/24"), 1);
98
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.1,!127.0.0.1"), -1);
104
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.1,!127.0.0.1"), -1);
99
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.1,10.0.0.1"), -1);
105
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.1,10.0.0.1"), -1);
100
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.1,127.0.0.2"), 0);
106
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.1,127.0.0.2"), 0);
101
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.2,10.0.0.1"), 0);
107
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.2,10.0.0.1"), 0);
102
	/* XXX negated ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.1,!127.0.0.2"), 1); */
108
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.1,!127.0.0.2"), 0);
103
	/* XXX negated ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.2,10.0.0.1"), 1); */
109
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.2,10.0.0.1"), 0);
110
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.1,127.0.0.0/8"), -1);
111
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.0/8,!127.0.0.1"), -1);
112
	ASSERT_INT_EQ(addr_match_list("127.0.0.2", "!127.0.0.1,127.0.0.0/8"), 1);
113
	ASSERT_INT_EQ(addr_match_list("127.0.0.2", "127.0.0.0/8,!127.0.0.1"), 1);
114
	ASSERT_INT_EQ(addr_match_list("127.0.0.2", "!127.0.1.0/24,!127.0.0.1"), 1);
115
	TEST_DONE();
116
117
	TEST_START("addr_match_list wildcard fallback");
118
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.*"), 1);
119
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "127.0.0.*"), 0);
120
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.1.*"), 0);
121
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "127.0.1.*"), 1);
122
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.*"), -1);
123
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "!127.0.0.*"), 1);
124
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.1.*"), 1);
125
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "!127.0.1.*"), -1);
126
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.0/8,127.0.0.*"), 1);
127
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "10.0.0.0/8,127.0.0.*"), 0);
128
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.0/8,127.0.1.*"), 0);
129
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "10.0.0.0/8,127.0.1.*"), 1);
130
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!10.0.0.0/8,!127.0.0.*"), -1);
131
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "!10.0.0.0/8,!127.0.0.*"), 1);
132
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!10.0.0.0/8,!127.0.1.*"), 1);
133
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "!10.0.0.0/8,!127.0.1.*"), -1);
134
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.*,!127.0.0.1"), -1);
135
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "127.0.*.*,!127.0.1.1"), -1);
136
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.1.*,!127.0.0.1"), -1);
137
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "127.0.1.*,!127.0.1.1"), -1);
138
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.*,!127.0.1.1"), -1);
139
	ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.1.*,!127.0.0.1"), -1);
140
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "!127.0.1.*,!127.0.0.1"), -1);
141
	ASSERT_INT_EQ(addr_match_list("127.0.1.1", "!127.0.0.*,!127.0.0.*,!172.0.0.0/8"), 1);
104
	TEST_DONE();
142
	TEST_DONE();
105
143
106
#define CHECK_FILTER(string,filter,expected) \
144
#define CHECK_FILTER(string,filter,expected) \
(-)a/ssh_config.5 (+4 lines)
Lines 1659-1664 pool, Link Here
1659
the following entry (in authorized_keys) could be used:
1659
the following entry (in authorized_keys) could be used:
1660
.Pp
1660
.Pp
1661
.Dl from=\&"!*.dialup.example.com,*.example.com\&"
1661
.Dl from=\&"!*.dialup.example.com,*.example.com\&"
1662
.Pp
1663
If a pattern-list contains a mixture of negated and non-negated patterns,
1664
at least one of the non-negated patterns must match for the result to be
1665
considered successful.
1662
.Sh TOKENS
1666
.Sh TOKENS
1663
Arguments to some keywords can make use of tokens,
1667
Arguments to some keywords can make use of tokens,
1664
which are expanded at runtime:
1668
which are expanded at runtime:

Return to bug 1918