Skip to content

Commit 76ea87c

Browse files
authored
refact whitelist/allowlist: net.IP to net/netip (#3683)
1 parent 02b2793 commit 76ea87c

File tree

10 files changed

+91
-86
lines changed

10 files changed

+91
-86
lines changed

pkg/apiserver/apic.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
"errors"
88
"fmt"
99
"math/rand"
10-
"net"
1110
"net/http"
11+
"net/netip"
1212
"net/url"
1313
"slices"
1414
"strings"
@@ -113,7 +113,7 @@ func (a *apic) FetchScenariosListFromDB(ctx context.Context) ([]string, error) {
113113
return scenarios, nil
114114
}
115115

116-
func decisionsToApiDecisions(decisions []*models.Decision) models.AddSignalsRequestItemDecisions {
116+
func decisionsToAPIDecisions(decisions []*models.Decision) models.AddSignalsRequestItemDecisions {
117117
apiDecisions := models.AddSignalsRequestItemDecisions{}
118118

119119
for _, decision := range decisions {
@@ -163,7 +163,7 @@ func alertToSignal(alert *models.Alert, scenarioTrust string, shareContext bool)
163163
CreatedAt: alert.CreatedAt,
164164
MachineID: alert.MachineID,
165165
ScenarioTrust: scenarioTrust,
166-
Decisions: decisionsToApiDecisions(alert.Decisions),
166+
Decisions: decisionsToAPIDecisions(alert.Decisions),
167167
UUID: alert.UUID,
168168
}
169169
if shareContext {
@@ -433,7 +433,7 @@ func (a *apic) CAPIPullIsOld(ctx context.Context) (bool, error) {
433433
}
434434

435435
if count > 0 {
436-
log.Printf("last CAPI pull is newer than 1h30, skip.")
436+
log.Info("last CAPI pull is newer than 1h30, skip.")
437437
return false, nil
438438
}
439439

@@ -844,26 +844,30 @@ func (a *apic) UpdateAllowlists(ctx context.Context, allowlistsLinks []*modelsca
844844

845845
// if decisions is whitelisted: return representation of the whitelist ip or cidr
846846
// if not whitelisted: empty string
847-
func (a *apic) whitelistedBy(decision *models.Decision, additionalIPs []net.IP, additionalRanges []*net.IPNet) string {
847+
func (a *apic) whitelistedBy(decision *models.Decision, additionalIPs []netip.Addr, additionalRanges []netip.Prefix) string {
848848
if decision.Value == nil {
849849
return ""
850850
}
851851

852-
ipval := net.ParseIP(*decision.Value)
852+
ipval, err := netip.ParseAddr(*decision.Value)
853+
if err != nil {
854+
return ""
855+
}
856+
853857
for _, cidr := range a.whitelists.Cidrs {
854858
if cidr.Contains(ipval) {
855859
return cidr.String()
856860
}
857861
}
858862

859863
for _, ip := range a.whitelists.Ips {
860-
if ip != nil && ip.Equal(ipval) {
864+
if ip == ipval {
861865
return ip.String()
862866
}
863867
}
864868

865869
for _, ip := range additionalIPs {
866-
if ip.Equal(ipval) {
870+
if ip == ipval {
867871
return ip.String()
868872
}
869873
}

pkg/apiserver/apic_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import (
55
"context"
66
"encoding/json"
77
"fmt"
8-
"net"
98
"net/http"
9+
"net/netip"
1010
"net/url"
1111
"os"
1212
"reflect"
@@ -57,12 +57,12 @@ func getAPIC(t *testing.T, ctx context.Context) *apic {
5757
return &apic{
5858
AlertsAddChan: make(chan []*models.Alert),
5959
// DecisionDeleteChan: make(chan []*models.Decision),
60-
dbClient: dbClient,
61-
mu: sync.Mutex{},
62-
startup: true,
63-
pullTomb: tomb.Tomb{},
64-
pushTomb: tomb.Tomb{},
65-
metricsTomb: tomb.Tomb{},
60+
dbClient: dbClient,
61+
mu: sync.Mutex{},
62+
startup: true,
63+
pullTomb: tomb.Tomb{},
64+
pushTomb: tomb.Tomb{},
65+
metricsTomb: tomb.Tomb{},
6666
consoleConfig: &csconfig.ConsoleConfig{
6767
ShareManualDecisions: ptr.Of(false),
6868
ShareTaintedScenarios: ptr.Of(false),
@@ -528,14 +528,14 @@ func TestAPICWhitelists(t *testing.T) {
528528
api := getAPIC(t, ctx)
529529
// one whitelist on IP, one on CIDR
530530
api.whitelists = &csconfig.CapiWhitelist{}
531-
api.whitelists.Ips = append(api.whitelists.Ips, net.ParseIP("9.2.3.4"), net.ParseIP("7.2.3.4"))
531+
api.whitelists.Ips = append(api.whitelists.Ips, netip.MustParseAddr("9.2.3.4"), netip.MustParseAddr("7.2.3.4"))
532532

533-
_, tnet, err := net.ParseCIDR("13.2.3.0/24")
533+
tnet, err := netip.ParsePrefix("13.2.3.0/24")
534534
require.NoError(t, err)
535535

536536
api.whitelists.Cidrs = append(api.whitelists.Cidrs, tnet)
537537

538-
_, tnet, err = net.ParseCIDR("11.2.3.0/24")
538+
tnet, err = netip.ParsePrefix("11.2.3.0/24")
539539
require.NoError(t, err)
540540

541541
api.whitelists.Cidrs = append(api.whitelists.Cidrs, tnet)

pkg/csconfig/api.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"io"
1010
"net"
11+
"net/netip"
1112
"os"
1213
"strings"
1314
"time"
@@ -276,8 +277,8 @@ func toValidCIDR(ip string) string {
276277
}
277278

278279
type CapiWhitelist struct {
279-
Ips []net.IP `yaml:"ips,omitempty"`
280-
Cidrs []*net.IPNet `yaml:"cidrs,omitempty"`
280+
Ips []netip.Addr `yaml:"ips,omitempty"`
281+
Cidrs []netip.Prefix `yaml:"cidrs,omitempty"`
281282
}
282283

283284
type LocalAPIAutoRegisterCfg struct {
@@ -356,7 +357,7 @@ func (c *Config) LoadAPIServer(inCli bool, skipOnlineCreds bool) error {
356357
}
357358

358359
if (c.API.Server.OnlineClient == nil || c.API.Server.OnlineClient.Credentials == nil) && !inCli {
359-
log.Printf("push and pull to Central API disabled")
360+
log.Info("push and pull to Central API disabled")
360361
}
361362

362363
// Set default values for CAPI push/pull
@@ -450,21 +451,21 @@ func parseCapiWhitelists(fd io.Reader) (*CapiWhitelist, error) {
450451
}
451452

452453
ret := &CapiWhitelist{
453-
Ips: make([]net.IP, len(fromCfg.Ips)),
454-
Cidrs: make([]*net.IPNet, len(fromCfg.Cidrs)),
454+
Ips: make([]netip.Addr, len(fromCfg.Ips)),
455+
Cidrs: make([]netip.Prefix, len(fromCfg.Cidrs)),
455456
}
456457

457458
for idx, v := range fromCfg.Ips {
458-
ip := net.ParseIP(v)
459-
if ip == nil {
460-
return nil, fmt.Errorf("invalid IP address: %s", v)
459+
ip, err := netip.ParseAddr(v)
460+
if err != nil {
461+
return nil, err
461462
}
462463

463464
ret.Ips[idx] = ip
464465
}
465466

466467
for idx, v := range fromCfg.Cidrs {
467-
_, tnet, err := net.ParseCIDR(v)
468+
tnet, err := netip.ParsePrefix(v)
468469
if err != nil {
469470
return nil, err
470471
}

pkg/csconfig/api_test.go

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package csconfig
22

33
import (
4-
"net"
4+
"net/netip"
55
"os"
66
"strings"
77
"testing"
@@ -271,13 +271,6 @@ func TestLoadAPIServer(t *testing.T) {
271271
}
272272
}
273273

274-
func mustParseCIDRNet(t *testing.T, s string) *net.IPNet {
275-
_, ipNet, err := net.ParseCIDR(s)
276-
require.NoError(t, err)
277-
278-
return ipNet
279-
}
280-
281274
func TestParseCapiWhitelists(t *testing.T) {
282275
tests := []struct {
283276
name string
@@ -289,33 +282,33 @@ func TestParseCapiWhitelists(t *testing.T) {
289282
name: "empty file",
290283
input: "",
291284
expected: &CapiWhitelist{
292-
Ips: []net.IP{},
293-
Cidrs: []*net.IPNet{},
285+
Ips: []netip.Addr{},
286+
Cidrs: []netip.Prefix{},
294287
},
295288
expectedErr: "empty file",
296289
},
297290
{
298291
name: "empty ip and cidr",
299292
input: `{"ips": [], "cidrs": []}`,
300293
expected: &CapiWhitelist{
301-
Ips: []net.IP{},
302-
Cidrs: []*net.IPNet{},
294+
Ips: []netip.Addr{},
295+
Cidrs: []netip.Prefix{},
303296
},
304297
},
305298
{
306299
name: "some ip",
307300
input: `{"ips": ["1.2.3.4"]}`,
308301
expected: &CapiWhitelist{
309-
Ips: []net.IP{net.IPv4(1, 2, 3, 4)},
310-
Cidrs: []*net.IPNet{},
302+
Ips: []netip.Addr{netip.MustParseAddr("1.2.3.4")},
303+
Cidrs: []netip.Prefix{},
311304
},
312305
},
313306
{
314307
name: "some cidr",
315308
input: `{"cidrs": ["1.2.3.0/24"]}`,
316309
expected: &CapiWhitelist{
317-
Ips: []net.IP{},
318-
Cidrs: []*net.IPNet{mustParseCIDRNet(t, "1.2.3.0/24")},
310+
Ips: []netip.Addr{},
311+
Cidrs: []netip.Prefix{netip.MustParsePrefix("1.2.3.0/24")},
319312
},
320313
},
321314
}

pkg/database/allowlists.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package database
33
import (
44
"context"
55
"fmt"
6-
"net"
6+
"net/netip"
77
"sort"
88
"strings"
99
"time"
@@ -360,31 +360,31 @@ func (c *Client) IsAllowlisted(ctx context.Context, value string) (bool, string,
360360
return true, reason, nil
361361
}
362362

363-
func (c *Client) GetAllowlistsContentForAPIC(ctx context.Context) ([]net.IP, []*net.IPNet, error) {
363+
func (c *Client) GetAllowlistsContentForAPIC(ctx context.Context) ([]netip.Addr, []netip.Prefix, error) {
364364
allowlists, err := c.ListAllowLists(ctx, true)
365365
if err != nil {
366366
return nil, nil, fmt.Errorf("unable to get allowlists: %w", err)
367367
}
368368

369369
var (
370-
ips []net.IP
371-
nets []*net.IPNet
370+
ips []netip.Addr
371+
nets []netip.Prefix
372372
)
373373

374374
for _, allowlist := range allowlists {
375375
for _, item := range allowlist.Edges.AllowlistItems {
376376
if item.ExpiresAt.IsZero() || item.ExpiresAt.After(time.Now().UTC()) {
377377
if strings.Contains(item.Value, "/") {
378-
_, ipNet, err := net.ParseCIDR(item.Value)
378+
ipNet, err := netip.ParsePrefix(item.Value)
379379
if err != nil {
380380
c.Log.Errorf("unable to parse CIDR %s: %s", item.Value, err)
381381
continue
382382
}
383383

384384
nets = append(nets, ipNet)
385385
} else {
386-
ip := net.ParseIP(item.Value)
387-
if ip == nil {
386+
ip, err := netip.ParseAddr(item.Value)
387+
if err != nil {
388388
c.Log.Errorf("unable to parse IP %s", item.Value)
389389
continue
390390
}

pkg/parser/whitelist.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package parser
22

33
import (
44
"fmt"
5-
"net"
5+
"net/netip"
66

77
"github.com/expr-lang/expr"
88
"github.com/expr-lang/expr/vm"
@@ -16,9 +16,9 @@ import (
1616
type Whitelist struct {
1717
Reason string `yaml:"reason,omitempty"`
1818
Ips []string `yaml:"ip,omitempty"`
19-
B_Ips []net.IP
19+
B_Ips []netip.Addr
2020
Cidrs []string `yaml:"cidr,omitempty"`
21-
B_Cidrs []*net.IPNet
21+
B_Cidrs []netip.Prefix
2222
Exprs []string `yaml:"expression,omitempty"`
2323
B_Exprs []*ExprWhitelist
2424
}
@@ -52,7 +52,7 @@ func (n *Node) CheckIPsWL(p *types.Event) bool {
5252
break
5353
}
5454
for _, v := range n.Whitelist.B_Ips {
55-
if v.Equal(src) {
55+
if v == src {
5656
n.Logger.Debugf("Event from [%s] is whitelisted by IP (%s), reason [%s]", src, v, n.Whitelist.Reason)
5757
isWhitelisted = true
5858
break
@@ -115,14 +115,19 @@ func (n *Node) CheckExprWL(cachedExprEnv map[string]interface{}, p *types.Event)
115115

116116
func (n *Node) CompileWLs() (bool, error) {
117117
for _, v := range n.Whitelist.Ips {
118-
n.Whitelist.B_Ips = append(n.Whitelist.B_Ips, net.ParseIP(v))
119-
n.Logger.Debugf("adding ip %s to whitelists", net.ParseIP(v))
118+
addr, err := netip.ParseAddr(v)
119+
if err != nil {
120+
return false, fmt.Errorf("parsing whitelist: %w", err)
121+
}
122+
123+
n.Whitelist.B_Ips = append(n.Whitelist.B_Ips, addr)
124+
n.Logger.Debugf("adding ip %s to whitelists", addr)
120125
}
121126

122127
for _, v := range n.Whitelist.Cidrs {
123-
_, tnet, err := net.ParseCIDR(v)
128+
tnet, err := netip.ParsePrefix(v)
124129
if err != nil {
125-
return false, fmt.Errorf("unable to parse cidr whitelist '%s' : %v", v, err)
130+
return false, fmt.Errorf("parsing whitelist: %w", err)
126131
}
127132
n.Whitelist.B_Cidrs = append(n.Whitelist.B_Cidrs, tnet)
128133
n.Logger.Debugf("adding cidr %s to whitelists", tnet)
@@ -131,7 +136,7 @@ func (n *Node) CompileWLs() (bool, error) {
131136
for _, filter := range n.Whitelist.Exprs {
132137
var err error
133138
expression := &ExprWhitelist{}
134-
expression.Filter, err = expr.Compile(filter, exprhelpers.GetExprOptions(map[string]interface{}{"evt": &types.Event{}})...)
139+
expression.Filter, err = expr.Compile(filter, exprhelpers.GetExprOptions(map[string]any{"evt": &types.Event{}})...)
135140
if err != nil {
136141
return false, fmt.Errorf("unable to compile whitelist expression '%s' : %v", filter, err)
137142
}

pkg/parser/whitelist_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestWhitelistCompile(t *testing.T) {
3838
"127.0.0.1/1000",
3939
},
4040
},
41-
expectedErr: "invalid CIDR address",
41+
expectedErr: `parsing whitelist: netip.ParsePrefix("127.0.0.1/1000"): prefix length out of range`,
4242
},
4343
{
4444
name: "Valid EXPR whitelist",

0 commit comments

Comments
 (0)