lib/api: Sanitize names used in certificates (fixes #7434) (#7435)

This commit is contained in:
Jakob Borg
2021-03-11 13:15:03 +01:00
committed by GitHub
parent cf838c71f7
commit df08984a58
2 changed files with 61 additions and 0 deletions
+40
View File
@@ -30,11 +30,15 @@ import (
"strconv"
"strings"
"time"
"unicode"
"github.com/julienschmidt/httprouter"
metrics "github.com/rcrowley/go-metrics"
"github.com/thejerf/suture/v4"
"github.com/vitrun/qart/qr"
"golang.org/x/text/runes"
"golang.org/x/text/transform"
"golang.org/x/text/unicode/norm"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
@@ -153,6 +157,10 @@ func (s *service) getListener(guiCfg config.GUIConfiguration) (net.Listener, err
if err != nil {
name = s.tlsDefaultCommonName
}
name, err = sanitizedHostname(name)
if err != nil {
name = s.tlsDefaultCommonName
}
cert, err = tlsutil.NewCertificate(httpsCertFile, httpsKeyFile, name, httpsCertLifetimeDays)
}
@@ -1895,6 +1903,38 @@ func errorString(err error) *string {
return nil
}
// sanitizedHostname returns the given name in a suitable form for use as
// the common name in a certificate, or an error.
func sanitizedHostname(name string) (string, error) {
// Remove diacritics and non-alphanumerics. This works by first
// transforming into normalization form D (things with diacriticals are
// split into the base character and the mark) and then removing
// undesired characters.
t := transform.Chain(
// Split runes with diacritics into base character and mark.
norm.NFD,
// Leave only [A-Za-z0-9-.].
runes.Remove(runes.Predicate(func(r rune) bool {
return r > unicode.MaxASCII ||
!unicode.IsLetter(r) && !unicode.IsNumber(r) &&
r != '.' && r != '-'
})))
name, _, err := transform.String(t, name)
if err != nil {
return "", err
}
// Name should not start or end with a dash or dot.
name = strings.Trim(name, "-.")
// Name should not be empty.
if name == "" {
return "", errors.New("no suitable name")
}
return strings.ToLower(name), nil
}
func isFolderNotFound(err error) bool {
for _, target := range []error{
model.ErrFolderMissing,