mirror of
https://github.com/octoleo/syncthing.git
synced 2025-02-02 03:48:26 +00:00
parent
cf838c71f7
commit
df08984a58
@ -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,
|
||||
|
@ -1370,6 +1370,27 @@ func TestConfigChanges(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSanitizedHostname(t *testing.T) {
|
||||
cases := []struct {
|
||||
in, out string
|
||||
}{
|
||||
{"foo.BAR-baz", "foo.bar-baz"},
|
||||
{"~.~-Min 1:a Räksmörgås-dator 😀😎 ~.~-", "min1araksmorgas-dator"},
|
||||
{"Vicenç-PC", "vicenc-pc"},
|
||||
{"~.~-~.~-", ""},
|
||||
{"", ""},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
res, err := sanitizedHostname(tc.in)
|
||||
if tc.out == "" && err == nil {
|
||||
t.Errorf("%q should cause error", tc.in)
|
||||
} else if res != tc.out {
|
||||
t.Errorf("%q => %q, expected %q", tc.in, res, tc.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func equalStrings(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
|
Loading…
x
Reference in New Issue
Block a user