utils.go 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2019 CNI authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package utils
  15. import (
  16. "bytes"
  17. "fmt"
  18. "regexp"
  19. "unicode"
  20. "github.com/containernetworking/cni/pkg/types"
  21. )
  22. const (
  23. // cniValidNameChars is the regexp used to validate valid characters in
  24. // containerID and networkName
  25. cniValidNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.\-]`
  26. // maxInterfaceNameLength is the length max of a valid interface name
  27. maxInterfaceNameLength = 15
  28. )
  29. var cniReg = regexp.MustCompile(`^` + cniValidNameChars + `*$`)
  30. // ValidateContainerID will validate that the supplied containerID is not empty does not contain invalid characters
  31. func ValidateContainerID(containerID string) *types.Error {
  32. if containerID == "" {
  33. return types.NewError(types.ErrUnknownContainer, "missing containerID", "")
  34. }
  35. if !cniReg.MatchString(containerID) {
  36. return types.NewError(types.ErrInvalidEnvironmentVariables, "invalid characters in containerID", containerID)
  37. }
  38. return nil
  39. }
  40. // ValidateNetworkName will validate that the supplied networkName does not contain invalid characters
  41. func ValidateNetworkName(networkName string) *types.Error {
  42. if networkName == "" {
  43. return types.NewError(types.ErrInvalidNetworkConfig, "missing network name:", "")
  44. }
  45. if !cniReg.MatchString(networkName) {
  46. return types.NewError(types.ErrInvalidNetworkConfig, "invalid characters found in network name", networkName)
  47. }
  48. return nil
  49. }
  50. // ValidateInterfaceName will validate the interface name based on the four rules below
  51. // 1. The name must not be empty
  52. // 2. The name must be less than 16 characters
  53. // 3. The name must not be "." or ".."
  54. // 4. The name must not contain / or : or any whitespace characters
  55. // ref to https://github.com/torvalds/linux/blob/master/net/core/dev.c#L1024
  56. func ValidateInterfaceName(ifName string) *types.Error {
  57. if len(ifName) == 0 {
  58. return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is empty", "")
  59. }
  60. if len(ifName) > maxInterfaceNameLength {
  61. return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is too long", fmt.Sprintf("interface name should be less than %d characters", maxInterfaceNameLength+1))
  62. }
  63. if ifName == "." || ifName == ".." {
  64. return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is . or ..", "")
  65. }
  66. for _, r := range bytes.Runes([]byte(ifName)) {
  67. if r == '/' || r == ':' || unicode.IsSpace(r) {
  68. return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name contains / or : or whitespace characters", "")
  69. }
  70. }
  71. return nil
  72. }