feat: ACL IDN (punycode domains) support

This commit is contained in:
Toby 2023-10-29 14:44:29 -07:00
parent affe092336
commit b2d4bac556
3 changed files with 65 additions and 4 deletions

View File

@ -10,6 +10,7 @@ require (
github.com/stretchr/testify v1.8.4
github.com/txthinking/socks5 v0.0.0-20230325130024-4230056ae301
golang.org/x/crypto v0.14.0
golang.org/x/net v0.17.0
google.golang.org/protobuf v1.28.1
)
@ -28,7 +29,6 @@ require (
go.uber.org/mock v0.3.0 // indirect
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.11.1 // indirect

View File

@ -2,6 +2,8 @@ package acl
import (
"net"
"golang.org/x/net/idna"
)
type hostMatcher interface {
@ -30,10 +32,14 @@ type domainMatcher struct {
}
func (m *domainMatcher) Match(host HostInfo) bool {
if m.Wildcard {
return deepMatchRune([]rune(host.Name), []rune(m.Pattern))
name, err := idna.ToUnicode(host.Name)
if err != nil {
name = host.Name
}
return m.Pattern == host.Name
if m.Wildcard {
return deepMatchRune([]rune(name), []rune(m.Pattern))
}
return name == m.Pattern
}
func deepMatchRune(str, pattern []rune) bool {

View File

@ -162,6 +162,17 @@ func Test_domainMatcher_Match(t *testing.T) {
},
want: true,
},
{
name: "non-wildcard IDN match",
fields: fields{
Pattern: "政府.中国",
Wildcard: false,
},
host: HostInfo{
Name: "xn--mxtq1m.xn--fiqs8s",
},
want: true,
},
{
name: "non-wildcard no match",
fields: fields{
@ -173,6 +184,17 @@ func Test_domainMatcher_Match(t *testing.T) {
},
want: false,
},
{
name: "non-wildcard IDN no match",
fields: fields{
Pattern: "政府.中国",
Wildcard: false,
},
host: HostInfo{
Name: "xn--mxtq1m.xn--yfro4i67o",
},
want: false,
},
{
name: "wildcard match 1",
fields: fields{
@ -195,6 +217,28 @@ func Test_domainMatcher_Match(t *testing.T) {
},
want: true,
},
{
name: "wildcard IDN match 1",
fields: fields{
Pattern: "战狼*.com",
Wildcard: true,
},
host: HostInfo{
Name: "xn--2-x14by21c.com",
},
want: true,
},
{
name: "wildcard IDN match 2",
fields: fields{
Pattern: "*大学*",
Wildcard: true,
},
host: HostInfo{
Name: "xn--xkry9kk1bz66a.xn--ses554g",
},
want: true,
},
{
name: "wildcard no match",
fields: fields{
@ -206,6 +250,17 @@ func Test_domainMatcher_Match(t *testing.T) {
},
want: false,
},
{
name: "wildcard IDN no match",
fields: fields{
Pattern: "*呵呵*",
Wildcard: true,
},
host: HostInfo{
Name: "xn--6qqt7juua.cn",
},
want: false,
},
{
name: "empty",
fields: fields{