safing-portmaster/spn/hub/format.go

69 lines
2.1 KiB
Go

package hub
import (
"fmt"
"net"
"regexp"
"github.com/safing/portmaster/service/network/netutils"
)
// BaselineCharset defines the permitted characters.
var BaselineCharset = regexp.MustCompile(
// Start of charset selection.
`^[` +
// Printable ASCII (character code 32-127), excluding common control characters of different languages: "$%&';<>\` and DELETE.
` !#()*+,\-\./0-9:=?@A-Z[\]^_a-z{|}~` +
// Only latin characters from extended ASCII (character code 128-255).
`ŠŒŽšœžŸ¡¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ` +
// End of charset selection.
`]*$`,
)
func checkStringFormat(fieldName, value string, maxLength int) error {
switch {
case len(value) > maxLength:
return fmt.Errorf("field %s with length of %d exceeds max length of %d", fieldName, len(value), maxLength)
case !BaselineCharset.MatchString(value):
return fmt.Errorf("field %s contains characters not permitted by baseline validation", fieldName)
default:
return nil
}
}
func checkStringSliceFormat(fieldName string, value []string, maxLength, maxStringLength int) error { //nolint:unparam
if len(value) > maxLength {
return fmt.Errorf("field %s with array/slice length of %d exceeds max length of %d", fieldName, len(value), maxLength)
}
for _, s := range value {
if err := checkStringFormat(fieldName, s, maxStringLength); err != nil {
return err
}
}
return nil
}
func checkByteSliceFormat(fieldName string, value []byte, maxLength int) error {
switch {
case len(value) > maxLength:
return fmt.Errorf("field %s with length of %d exceeds max length of %d", fieldName, len(value), maxLength)
default:
return nil
}
}
func checkIPFormat(fieldName string, value net.IP) error {
// Check if there is an IP address.
if value == nil {
return nil
}
switch {
case len(value) != 4 && len(value) != 16:
return fmt.Errorf("field %s has an invalid length of %d for an IP address", fieldName, len(value))
case netutils.GetIPScope(value) == netutils.Invalid:
return fmt.Errorf("field %s holds an invalid IP address: %s", fieldName, value)
default:
return nil
}
}