gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/grpc/internal/credentials/xds/handshake_info_test.go (about) 1 /* 2 * 3 * Copyright 2021 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package xds 20 21 import ( 22 "net" 23 "net/url" 24 "regexp" 25 "testing" 26 27 "gitee.com/zhaochuninhefei/gmgo/x509" 28 29 "gitee.com/zhaochuninhefei/gmgo/grpc/internal/xds/matcher" 30 ) 31 32 func TestDNSMatch(t *testing.T) { 33 tests := []struct { 34 desc string 35 host string 36 pattern string 37 wantMatch bool 38 }{ 39 { 40 desc: "invalid wildcard 1", 41 host: "aa.example.com", 42 pattern: "*a.example.com", 43 wantMatch: false, 44 }, 45 { 46 desc: "invalid wildcard 2", 47 host: "aa.example.com", 48 pattern: "a*.example.com", 49 wantMatch: false, 50 }, 51 { 52 desc: "invalid wildcard 3", 53 host: "abc.example.com", 54 pattern: "a*c.example.com", 55 wantMatch: false, 56 }, 57 { 58 desc: "wildcard in one of the middle components", 59 host: "abc.test.example.com", 60 pattern: "abc.*.example.com", 61 wantMatch: false, 62 }, 63 { 64 desc: "single component wildcard", 65 host: "a.example.com", 66 pattern: "*", 67 wantMatch: false, 68 }, 69 { 70 desc: "short host name", 71 host: "a.com", 72 pattern: "*.example.com", 73 wantMatch: false, 74 }, 75 { 76 desc: "suffix mismatch", 77 host: "a.notexample.com", 78 pattern: "*.example.com", 79 wantMatch: false, 80 }, 81 { 82 desc: "wildcard match across components", 83 host: "sub.test.example.com", 84 pattern: "*.example.com.", 85 wantMatch: false, 86 }, 87 { 88 desc: "host doesn't end in period", 89 host: "test.example.com", 90 pattern: "test.example.com.", 91 wantMatch: true, 92 }, 93 { 94 desc: "pattern doesn't end in period", 95 host: "test.example.com.", 96 pattern: "test.example.com", 97 wantMatch: true, 98 }, 99 { 100 desc: "case insensitive", 101 host: "TEST.EXAMPLE.COM.", 102 pattern: "test.example.com.", 103 wantMatch: true, 104 }, 105 { 106 desc: "simple match", 107 host: "test.example.com", 108 pattern: "test.example.com", 109 wantMatch: true, 110 }, 111 { 112 desc: "good wildcard", 113 host: "a.example.com", 114 pattern: "*.example.com", 115 wantMatch: true, 116 }, 117 } 118 119 for _, test := range tests { 120 t.Run(test.desc, func(t *testing.T) { 121 gotMatch := dnsMatch(test.host, test.pattern) 122 if gotMatch != test.wantMatch { 123 t.Fatalf("dnsMatch(%s, %s) = %v, want %v", test.host, test.pattern, gotMatch, test.wantMatch) 124 } 125 }) 126 } 127 } 128 129 //goland:noinspection HttpUrlsUsage 130 func TestMatchingSANExists_FailureCases(t *testing.T) { 131 url1, err := url.Parse("http://golang.org") 132 if err != nil { 133 t.Fatalf("url.Parse() failed: %v", err) 134 } 135 url2, err := url.Parse("https://github.com/grpc/grpc-go") 136 if err != nil { 137 t.Fatalf("url.Parse() failed: %v", err) 138 } 139 inputCert := &x509.Certificate{ 140 DNSNames: []string{"foo.bar.example.com", "bar.baz.test.com", "*.example.com"}, 141 EmailAddresses: []string{"foobar@example.com", "barbaz@test.com"}, 142 IPAddresses: []net.IP{net.ParseIP("192.0.0.1"), net.ParseIP("2001:db8::68")}, 143 URIs: []*url.URL{url1, url2}, 144 } 145 146 tests := []struct { 147 desc string 148 sanMatchers []matcher.StringMatcher 149 }{ 150 { 151 desc: "exact match", 152 sanMatchers: []matcher.StringMatcher{ 153 matcher.StringMatcherForTesting(newStringP("abcd.test.com"), nil, nil, nil, nil, false), 154 matcher.StringMatcherForTesting(newStringP("http://golang"), nil, nil, nil, nil, false), 155 matcher.StringMatcherForTesting(newStringP("HTTP://GOLANG.ORG"), nil, nil, nil, nil, false), 156 }, 157 }, 158 { 159 desc: "prefix match", 160 sanMatchers: []matcher.StringMatcher{ 161 matcher.StringMatcherForTesting(nil, newStringP("i-aint-the-one"), nil, nil, nil, false), 162 matcher.StringMatcherForTesting(nil, newStringP("192.168.1.1"), nil, nil, nil, false), 163 matcher.StringMatcherForTesting(nil, newStringP("FOO.BAR"), nil, nil, nil, false), 164 }, 165 }, 166 { 167 desc: "suffix match", 168 sanMatchers: []matcher.StringMatcher{ 169 matcher.StringMatcherForTesting(nil, nil, newStringP("i-aint-the-one"), nil, nil, false), 170 matcher.StringMatcherForTesting(nil, nil, newStringP("1::68"), nil, nil, false), 171 matcher.StringMatcherForTesting(nil, nil, newStringP(".COM"), nil, nil, false), 172 }, 173 }, 174 { 175 desc: "regex match", 176 sanMatchers: []matcher.StringMatcher{ 177 matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`.*\.examples\.com`), false), 178 matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`192\.[0-9]{1,3}\.1\.1`), false), 179 }, 180 }, 181 { 182 desc: "contains match", 183 sanMatchers: []matcher.StringMatcher{ 184 matcher.StringMatcherForTesting(nil, nil, nil, newStringP("i-aint-the-one"), nil, false), 185 matcher.StringMatcherForTesting(nil, nil, nil, newStringP("2001:db8:1:1::68"), nil, false), 186 matcher.StringMatcherForTesting(nil, nil, nil, newStringP("GRPC"), nil, false), 187 }, 188 }, 189 } 190 191 for _, test := range tests { 192 t.Run(test.desc, func(t *testing.T) { 193 hi := NewHandshakeInfo(nil, nil) 194 hi.SetSANMatchers(test.sanMatchers) 195 196 if hi.MatchingSANExists(inputCert) { 197 t.Fatalf("hi.MatchingSANExists(%+v) with SAN matchers +%v succeeded when expected to fail", inputCert, test.sanMatchers) 198 } 199 }) 200 } 201 } 202 203 //goland:noinspection HttpUrlsUsage 204 func TestMatchingSANExists_Success(t *testing.T) { 205 url1, err := url.Parse("http://golang.org") 206 if err != nil { 207 t.Fatalf("url.Parse() failed: %v", err) 208 } 209 url2, err := url.Parse("https://github.com/grpc/grpc-go") 210 if err != nil { 211 t.Fatalf("url.Parse() failed: %v", err) 212 } 213 inputCert := &x509.Certificate{ 214 DNSNames: []string{"baz.test.com", "*.example.com"}, 215 EmailAddresses: []string{"foobar@example.com", "barbaz@test.com"}, 216 IPAddresses: []net.IP{net.ParseIP("192.0.0.1"), net.ParseIP("2001:db8::68")}, 217 URIs: []*url.URL{url1, url2}, 218 } 219 220 tests := []struct { 221 desc string 222 sanMatchers []matcher.StringMatcher 223 }{ 224 { 225 desc: "no san matchers", 226 }, 227 { 228 desc: "exact match dns wildcard", 229 sanMatchers: []matcher.StringMatcher{ 230 matcher.StringMatcherForTesting(nil, newStringP("192.168.1.1"), nil, nil, nil, false), 231 matcher.StringMatcherForTesting(newStringP("https://github.com/grpc/grpc-java"), nil, nil, nil, nil, false), 232 matcher.StringMatcherForTesting(newStringP("abc.example.com"), nil, nil, nil, nil, false), 233 }, 234 }, 235 { 236 desc: "exact match ignore case", 237 sanMatchers: []matcher.StringMatcher{ 238 matcher.StringMatcherForTesting(newStringP("FOOBAR@EXAMPLE.COM"), nil, nil, nil, nil, true), 239 }, 240 }, 241 { 242 desc: "prefix match", 243 sanMatchers: []matcher.StringMatcher{ 244 matcher.StringMatcherForTesting(nil, nil, newStringP(".co.in"), nil, nil, false), 245 matcher.StringMatcherForTesting(nil, newStringP("192.168.1.1"), nil, nil, nil, false), 246 matcher.StringMatcherForTesting(nil, newStringP("baz.test"), nil, nil, nil, false), 247 }, 248 }, 249 { 250 desc: "prefix match ignore case", 251 sanMatchers: []matcher.StringMatcher{ 252 matcher.StringMatcherForTesting(nil, newStringP("BAZ.test"), nil, nil, nil, true), 253 }, 254 }, 255 { 256 desc: "suffix match", 257 sanMatchers: []matcher.StringMatcher{ 258 matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`192\.[0-9]{1,3}\.1\.1`), false), 259 matcher.StringMatcherForTesting(nil, nil, newStringP("192.168.1.1"), nil, nil, false), 260 matcher.StringMatcherForTesting(nil, nil, newStringP("@test.com"), nil, nil, false), 261 }, 262 }, 263 { 264 desc: "suffix match ignore case", 265 sanMatchers: []matcher.StringMatcher{ 266 matcher.StringMatcherForTesting(nil, nil, newStringP("@test.COM"), nil, nil, true), 267 }, 268 }, 269 { 270 desc: "regex match", 271 sanMatchers: []matcher.StringMatcher{ 272 matcher.StringMatcherForTesting(nil, nil, nil, newStringP("https://github.com/grpc/grpc-java"), nil, false), 273 matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`192\.[0-9]{1,3}\.1\.1`), false), 274 matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`.*\.test\.com`), false), 275 }, 276 }, 277 { 278 desc: "contains match", 279 sanMatchers: []matcher.StringMatcher{ 280 matcher.StringMatcherForTesting(newStringP("https://github.com/grpc/grpc-java"), nil, nil, nil, nil, false), 281 matcher.StringMatcherForTesting(nil, nil, nil, newStringP("2001:68::db8"), nil, false), 282 matcher.StringMatcherForTesting(nil, nil, nil, newStringP("192.0.0"), nil, false), 283 }, 284 }, 285 { 286 desc: "contains match ignore case", 287 sanMatchers: []matcher.StringMatcher{ 288 matcher.StringMatcherForTesting(nil, nil, nil, newStringP("GRPC"), nil, true), 289 }, 290 }, 291 } 292 293 for _, test := range tests { 294 t.Run(test.desc, func(t *testing.T) { 295 hi := NewHandshakeInfo(nil, nil) 296 hi.SetSANMatchers(test.sanMatchers) 297 298 if !hi.MatchingSANExists(inputCert) { 299 t.Fatalf("hi.MatchingSANExists(%+v) with SAN matchers +%v failed when expected to succeed", inputCert, test.sanMatchers) 300 } 301 }) 302 } 303 } 304 305 func newStringP(s string) *string { 306 return &s 307 }