// ValidateCIDRListString checks if the list of CIDR blocks are valid, given // that the input is a string composed by joining all the CIDR blocks using a // separator. The input is separated based on the given separator and validity // of each is checked. func ValidateCIDRListString(cidrList string, separator string) (bool, error) { if cidrList == "" { return false, fmt.Errorf("missing CIDR list that needs validation") } if separator == "" { return false, fmt.Errorf("missing separator") } return ValidateCIDRListSlice(strutil.ParseDedupAndSortStrings(cidrList, separator)) }
// verifyCIDRRoleSecretIDSubset checks if the CIDR blocks set on the secret ID // are a subset of CIDR blocks set on the role func verifyCIDRRoleSecretIDSubset(secretIDCIDRs []string, roleBoundCIDRList string) error { if len(secretIDCIDRs) != 0 { // Parse the CIDRs on role as a slice roleCIDRs := strutil.ParseDedupAndSortStrings(roleBoundCIDRList, ",") // If there are no CIDR blocks on the role, then the subset // requirement would be satisfied if len(roleCIDRs) != 0 { subset, err := cidrutil.SubsetBlocks(roleCIDRs, secretIDCIDRs) if !subset || err != nil { return fmt.Errorf("failed to verify subset relationship between CIDR blocks on the role %q and CIDR blocks on the secret ID %q: %v", roleCIDRs, secretIDCIDRs, err) } } } return nil }
// IPBelongsToCIDRBlocksString checks if the given IP is encompassed by any of // the given CIDR blocks, when the input is a string composed by joining all // the CIDR blocks using a separator. The input is separated based on the given // separator and the IP is checked to be belonged by any CIDR block. func IPBelongsToCIDRBlocksString(ipAddr string, cidrList, separator string) (bool, error) { if ipAddr == "" { return false, fmt.Errorf("missing IP address") } if cidrList == "" { return false, fmt.Errorf("missing CIDR list") } if separator == "" { return false, fmt.Errorf("missing separator") } if ip := net.ParseIP(ipAddr); ip == nil { return false, fmt.Errorf("invalid IP address") } return IPBelongsToCIDRBlocksSlice(ipAddr, strutil.ParseDedupAndSortStrings(cidrList, separator)) }
// newConsulBackend constructs a Consul backend using the given API client // and the prefix in the KV store. func newConsulBackend(conf map[string]string, logger *log.Logger) (Backend, error) { // Get the path in Consul path, ok := conf["path"] if !ok { path = "vault/" } logger.Printf("[DEBUG]: physical/consul: config path set to %v", path) // Ensure path is suffixed but not prefixed if !strings.HasSuffix(path, "/") { logger.Printf("[WARN]: physical/consul: appending trailing forward slash to path") path += "/" } if strings.HasPrefix(path, "/") { logger.Printf("[WARN]: physical/consul: trimming path of its forward slash") path = strings.TrimPrefix(path, "/") } // Allow admins to disable consul integration disableReg, ok := conf["disable_registration"] var disableRegistration bool if ok && disableReg != "" { b, err := strconv.ParseBool(disableReg) if err != nil { return nil, errwrap.Wrapf("failed parsing disable_registration parameter: {{err}}", err) } disableRegistration = b } logger.Printf("[DEBUG]: physical/consul: config disable_registration set to %v", disableRegistration) // Get the service name to advertise in Consul service, ok := conf["service"] if !ok { service = DefaultServiceName } logger.Printf("[DEBUG]: physical/consul: config service set to %s", service) // Get the additional tags to attach to the registered service name tags := conf["service_tags"] logger.Printf("[DEBUG]: physical/consul: config service_tags set to %s", tags) checkTimeout := defaultCheckTimeout checkTimeoutStr, ok := conf["check_timeout"] if ok { d, err := time.ParseDuration(checkTimeoutStr) if err != nil { return nil, err } min, _ := lib.DurationMinusBufferDomain(d, checkMinBuffer, checkJitterFactor) if min < checkMinBuffer { return nil, fmt.Errorf("Consul check_timeout must be greater than %v", min) } checkTimeout = d logger.Printf("[DEBUG]: physical/consul: config check_timeout set to %v", d) } // Configure the client consulConf := api.DefaultConfig() if addr, ok := conf["address"]; ok { consulConf.Address = addr logger.Printf("[DEBUG]: physical/consul: config address set to %s", addr) } if scheme, ok := conf["scheme"]; ok { consulConf.Scheme = scheme logger.Printf("[DEBUG]: physical/consul: config scheme set to %s", scheme) } if token, ok := conf["token"]; ok { consulConf.Token = token logger.Printf("[DEBUG]: physical/consul: config token set") } if consulConf.Scheme == "https" { tlsClientConfig, err := setupTLSConfig(conf) if err != nil { return nil, err } transport := cleanhttp.DefaultPooledTransport() transport.MaxIdleConnsPerHost = 4 transport.TLSClientConfig = tlsClientConfig consulConf.HttpClient.Transport = transport logger.Printf("[DEBUG]: physical/consul: configured TLS") } client, err := api.NewClient(consulConf) if err != nil { return nil, errwrap.Wrapf("client setup failed: {{err}}", err) } maxParStr, ok := conf["max_parallel"] var maxParInt int if ok { maxParInt, err = strconv.Atoi(maxParStr) if err != nil { return nil, errwrap.Wrapf("failed parsing max_parallel parameter: {{err}}", err) } logger.Printf("[DEBUG]: physical/consul: max_parallel set to %d", maxParInt) } // Setup the backend c := &ConsulBackend{ path: path, logger: logger, client: client, kv: client.KV(), permitPool: NewPermitPool(maxParInt), serviceName: service, serviceTags: strutil.ParseDedupAndSortStrings(tags, ","), checkTimeout: checkTimeout, disableRegistration: disableRegistration, } return c, nil }