From 761722395d9565455f67f8ab49e5d1afbf12a856 Mon Sep 17 00:00:00 2001 From: allencloud Date: Mon, 17 Oct 2016 23:37:10 +0800 Subject: [PATCH] validate network and endpoint name more strictly Signed-off-by: allencloud --- libnetwork/config/config.go | 18 +++++++++++++----- libnetwork/config/config_test.go | 9 ++++++--- libnetwork/controller.go | 4 ++-- libnetwork/error.go | 2 +- libnetwork/network.go | 5 +++-- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/libnetwork/config/config.go b/libnetwork/config/config.go index 8c3af13b22..a6ebd05284 100644 --- a/libnetwork/config/config.go +++ b/libnetwork/config/config.go @@ -1,6 +1,8 @@ package config import ( + "fmt" + "regexp" "strings" "github.com/BurntSushi/toml" @@ -15,6 +17,12 @@ import ( "github.com/docker/libnetwork/osl" ) +// RestrictedNameChars collects the characters allowed to represent a network or endpoint name. +const restrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]` + +// RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters. +var restrictedNamePattern = regexp.MustCompile(`^/?` + restrictedNameChars + `+$`) + // Config encapsulates configurations of various Libnetwork components type Config struct { Daemon DaemonCfg @@ -223,12 +231,12 @@ func (c *Config) ProcessOptions(options ...Option) { } } -// IsValidName validates configuration objects supported by libnetwork -func IsValidName(name string) bool { - if strings.TrimSpace(name) == "" { - return false +// ValidateName validates configuration objects supported by libnetwork +func ValidateName(name string) error { + if !restrictedNamePattern.MatchString(name) { + return fmt.Errorf("%s includes invalid characters, only %q are allowed", name, restrictedNameChars) } - return true + return nil } // OptionLocalKVProvider function returns an option setter for kvstore provider diff --git a/libnetwork/config/config_test.go b/libnetwork/config/config_test.go index ade9f746cd..a5feebac58 100644 --- a/libnetwork/config/config_test.go +++ b/libnetwork/config/config_test.go @@ -46,13 +46,16 @@ func TestOptionsLabels(t *testing.T) { } func TestValidName(t *testing.T) { - if !IsValidName("test") { + if err := ValidateName("test"); err != nil { t.Fatal("Name validation fails for a name that must be accepted") } - if IsValidName("") { + if err := ValidateName(""); err == nil { t.Fatal("Name validation succeeds for a case when it is expected to fail") } - if IsValidName(" ") { + if err := ValidateName(" "); err == nil { + t.Fatal("Name validation succeeds for a case when it is expected to fail") + } + if err := ValidateName("<>$$^"); err == nil { t.Fatal("Name validation succeeds for a case when it is expected to fail") } } diff --git a/libnetwork/controller.go b/libnetwork/controller.go index 914287a5be..c86df6686f 100644 --- a/libnetwork/controller.go +++ b/libnetwork/controller.go @@ -626,8 +626,8 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ... } } - if !config.IsValidName(name) { - return nil, ErrInvalidName(name) + if err := config.ValidateName(name); err != nil { + return nil, ErrInvalidName(err.Error()) } if id == "" { diff --git a/libnetwork/error.go b/libnetwork/error.go index d1291f1db6..6c41bf166a 100644 --- a/libnetwork/error.go +++ b/libnetwork/error.go @@ -69,7 +69,7 @@ func (ii ErrInvalidID) Error() string { func (ii ErrInvalidID) BadRequest() {} // ErrInvalidName is returned when a query-by-name or resource create method is -// invoked with an empty name parameter +// invoked with an invalid name parameter type ErrInvalidName string func (in ErrInvalidName) Error() string { diff --git a/libnetwork/network.go b/libnetwork/network.go index 8a068d22e9..eebb46ffb2 100644 --- a/libnetwork/network.go +++ b/libnetwork/network.go @@ -848,8 +848,9 @@ func (n *network) addEndpoint(ep *endpoint) error { func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) { var err error - if !config.IsValidName(name) { - return nil, ErrInvalidName(name) + + if err = config.ValidateName(name); err != nil { + return nil, ErrInvalidName(err.Error()) } if _, err = n.EndpointByName(name); err == nil {