2022-10-06 14:23:59 +02:00
|
|
|
package actions
|
|
|
|
|
|
|
|
import (
|
2025-04-25 09:12:42 +02:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2022-10-06 14:23:59 +02:00
|
|
|
"net"
|
|
|
|
"reflect"
|
2024-02-16 17:04:42 +01:00
|
|
|
"strings"
|
2022-10-06 14:23:59 +02:00
|
|
|
|
|
|
|
"github.com/mitchellh/mapstructure"
|
|
|
|
)
|
|
|
|
|
|
|
|
func SetHTTPConfig(config *HTTPConfig) {
|
|
|
|
httpConfig = config
|
|
|
|
}
|
|
|
|
|
|
|
|
var httpConfig *HTTPConfig
|
|
|
|
|
|
|
|
type HTTPConfig struct {
|
|
|
|
DenyList []AddressChecker
|
|
|
|
}
|
|
|
|
|
|
|
|
func HTTPConfigDecodeHook(from, to reflect.Value) (interface{}, error) {
|
|
|
|
if to.Type() != reflect.TypeOf(HTTPConfig{}) {
|
|
|
|
return from.Interface(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
config := struct {
|
|
|
|
DenyList []string
|
|
|
|
}{}
|
|
|
|
|
|
|
|
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
|
|
|
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
|
|
|
|
WeaklyTypedInput: true,
|
|
|
|
Result: &config,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = decoder.Decode(from.Interface()); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
c := HTTPConfig{
|
2024-02-16 17:04:42 +01:00
|
|
|
DenyList: make([]AddressChecker, 0),
|
2022-10-06 14:23:59 +02:00
|
|
|
}
|
|
|
|
|
2024-02-16 17:04:42 +01:00
|
|
|
for _, unsplit := range config.DenyList {
|
|
|
|
for _, split := range strings.Split(unsplit, ",") {
|
2024-10-22 16:16:44 +02:00
|
|
|
parsed, parseErr := NewHostChecker(split)
|
2024-02-16 17:04:42 +01:00
|
|
|
if parseErr != nil {
|
|
|
|
return nil, parseErr
|
|
|
|
}
|
|
|
|
if parsed != nil {
|
|
|
|
c.DenyList = append(c.DenyList, parsed)
|
|
|
|
}
|
2022-10-06 14:23:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return c, nil
|
|
|
|
}
|
|
|
|
|
2024-10-22 16:16:44 +02:00
|
|
|
func NewHostChecker(entry string) (AddressChecker, error) {
|
2025-04-25 09:12:42 +02:00
|
|
|
if entry == "" {
|
|
|
|
return nil, nil
|
|
|
|
}
|
2024-10-22 16:16:44 +02:00
|
|
|
_, network, err := net.ParseCIDR(entry)
|
2022-10-06 14:23:59 +02:00
|
|
|
if err == nil {
|
2024-10-22 16:16:44 +02:00
|
|
|
return &HostChecker{Net: network}, nil
|
2022-10-06 14:23:59 +02:00
|
|
|
}
|
2024-10-22 16:16:44 +02:00
|
|
|
if ip := net.ParseIP(entry); ip != nil {
|
|
|
|
return &HostChecker{IP: ip}, nil
|
2022-10-06 14:23:59 +02:00
|
|
|
}
|
2024-10-22 16:16:44 +02:00
|
|
|
return &HostChecker{Domain: entry}, nil
|
2022-10-06 14:23:59 +02:00
|
|
|
}
|
|
|
|
|
2024-10-22 16:16:44 +02:00
|
|
|
type HostChecker struct {
|
|
|
|
Net *net.IPNet
|
|
|
|
IP net.IP
|
|
|
|
Domain string
|
2022-10-06 14:23:59 +02:00
|
|
|
}
|
|
|
|
|
2025-04-25 09:12:42 +02:00
|
|
|
type AddressDeniedError struct {
|
|
|
|
deniedBy string
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewAddressDeniedError(deniedBy string) *AddressDeniedError {
|
|
|
|
return &AddressDeniedError{deniedBy: deniedBy}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *AddressDeniedError) Error() string {
|
|
|
|
return fmt.Sprintf("address is denied by '%s'", e.deniedBy)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *AddressDeniedError) Is(target error) bool {
|
|
|
|
var addressDeniedErr *AddressDeniedError
|
|
|
|
if !errors.As(target, &addressDeniedErr) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return e.deniedBy == addressDeniedErr.deniedBy
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *HostChecker) IsDenied(ips []net.IP, address string) error {
|
2024-10-22 16:16:44 +02:00
|
|
|
// if the address matches the domain, no additional checks as needed
|
|
|
|
if c.Domain == address {
|
2025-04-25 09:12:42 +02:00
|
|
|
return NewAddressDeniedError(c.Domain)
|
2022-10-06 14:23:59 +02:00
|
|
|
}
|
2024-10-22 16:16:44 +02:00
|
|
|
// otherwise we need to check on ips (incl. the resolved ips of the host)
|
|
|
|
for _, ip := range ips {
|
|
|
|
if c.Net != nil && c.Net.Contains(ip) {
|
2025-04-25 09:12:42 +02:00
|
|
|
return NewAddressDeniedError(c.Net.String())
|
2024-10-22 16:16:44 +02:00
|
|
|
}
|
|
|
|
if c.IP != nil && c.IP.Equal(ip) {
|
2025-04-25 09:12:42 +02:00
|
|
|
return NewAddressDeniedError(c.IP.String())
|
2024-10-22 16:16:44 +02:00
|
|
|
}
|
2022-10-06 14:23:59 +02:00
|
|
|
}
|
2025-04-25 09:12:42 +02:00
|
|
|
return nil
|
2022-10-06 14:23:59 +02:00
|
|
|
}
|