Browse code

Merge pull request #1510 from allencloud/validate-network-and-endpoint-name-strictly

validate network and endpoint name more strictly

Jana Radhakrishnan authored on 2016/11/03 01:57:50
Showing 5 changed files
... ...
@@ -1,6 +1,8 @@
1 1
 package config
2 2
 
3 3
 import (
4
+	"fmt"
5
+	"regexp"
4 6
 	"strings"
5 7
 
6 8
 	"github.com/BurntSushi/toml"
... ...
@@ -15,6 +17,12 @@ import (
15 15
 	"github.com/docker/libnetwork/osl"
16 16
 )
17 17
 
18
+// RestrictedNameChars collects the characters allowed to represent a network or endpoint name.
19
+const restrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]`
20
+
21
+// RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters.
22
+var restrictedNamePattern = regexp.MustCompile(`^/?` + restrictedNameChars + `+$`)
23
+
18 24
 // Config encapsulates configurations of various Libnetwork components
19 25
 type Config struct {
20 26
 	Daemon          DaemonCfg
... ...
@@ -223,12 +231,12 @@ func (c *Config) ProcessOptions(options ...Option) {
223 223
 	}
224 224
 }
225 225
 
226
-// IsValidName validates configuration objects supported by libnetwork
227
-func IsValidName(name string) bool {
228
-	if strings.TrimSpace(name) == "" {
229
-		return false
226
+// ValidateName validates configuration objects supported by libnetwork
227
+func ValidateName(name string) error {
228
+	if !restrictedNamePattern.MatchString(name) {
229
+		return fmt.Errorf("%s includes invalid characters, only %q are allowed", name, restrictedNameChars)
230 230
 	}
231
-	return true
231
+	return nil
232 232
 }
233 233
 
234 234
 // OptionLocalKVProvider function returns an option setter for kvstore provider
... ...
@@ -46,13 +46,16 @@ func TestOptionsLabels(t *testing.T) {
46 46
 }
47 47
 
48 48
 func TestValidName(t *testing.T) {
49
-	if !IsValidName("test") {
49
+	if err := ValidateName("test"); err != nil {
50 50
 		t.Fatal("Name validation fails for a name that must be accepted")
51 51
 	}
52
-	if IsValidName("") {
52
+	if err := ValidateName(""); err == nil {
53 53
 		t.Fatal("Name validation succeeds for a case when it is expected to fail")
54 54
 	}
55
-	if IsValidName("   ") {
55
+	if err := ValidateName("   "); err == nil {
56
+		t.Fatal("Name validation succeeds for a case when it is expected to fail")
57
+	}
58
+	if err := ValidateName("<>$$^"); err == nil {
56 59
 		t.Fatal("Name validation succeeds for a case when it is expected to fail")
57 60
 	}
58 61
 }
... ...
@@ -626,8 +626,8 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
626 626
 		}
627 627
 	}
628 628
 
629
-	if !config.IsValidName(name) {
630
-		return nil, ErrInvalidName(name)
629
+	if err := config.ValidateName(name); err != nil {
630
+		return nil, ErrInvalidName(err.Error())
631 631
 	}
632 632
 
633 633
 	if id == "" {
... ...
@@ -69,7 +69,7 @@ func (ii ErrInvalidID) Error() string {
69 69
 func (ii ErrInvalidID) BadRequest() {}
70 70
 
71 71
 // ErrInvalidName is returned when a query-by-name or resource create method is
72
-// invoked with an empty name parameter
72
+// invoked with an invalid name parameter
73 73
 type ErrInvalidName string
74 74
 
75 75
 func (in ErrInvalidName) Error() string {
... ...
@@ -848,8 +848,9 @@ func (n *network) addEndpoint(ep *endpoint) error {
848 848
 
849 849
 func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
850 850
 	var err error
851
-	if !config.IsValidName(name) {
852
-		return nil, ErrInvalidName(name)
851
+
852
+	if err = config.ValidateName(name); err != nil {
853
+		return nil, ErrInvalidName(err.Error())
853 854
 	}
854 855
 
855 856
 	if _, err = n.EndpointByName(name); err == nil {