def is_ip_or_alias(self, address): """ return True if address is an ip or an alias """ # Is it an alias? if (self.find_alias(address, 'host') is not None or self.find_alias(address, 'network') is not None or self.find_alias(address, 'urltable') is not None or self.find_alias(address, 'urltable_ports') is not None): return True # Is it an IP address? try: ip_address(u'{0}'.format(address)) return True except ValueError: pass # Is it an IP network? try: ip_network(u'{0}'.format(address)) return True except ValueError: pass # None of the above return False
def is_ip_address(address): """ test if address is a valid ip address """ try: ip_address(u'{0}'.format(address)) return True except ValueError: pass return False
def isipaddress(data): """ Checks if the passed string is a valid IPv4 or IPv6 address """ isipaddress = True try: ipaddress.ip_address(data) except ValueError: isipaddress = False return isipaddress
def _normalize_san(self, san): if san.startswith('IP Address:'): san = 'IP:' + san[len('IP Address:'):] if san.startswith('IP:'): ip = compat_ipaddress.ip_address(san[3:]) san = 'IP:{0}'.format(ip.compressed) return san
def is_ipv4_address(address): """ test if address is a valid ipv4 address """ try: addr = ip_address(u'{0}'.format(address)) return isinstance(addr, IPv4Address) except ValueError: pass return False
def _get_challenge_data(self, auth, identifier_type, identifier): ''' Returns a dict with the data for all proposed (and supported) challenges of the given authorization. ''' data = {} # no need to choose a specific challenge here as this module # is not responsible for fulfilling the challenges. Calculate # and return the required information for each challenge. for challenge in auth['challenges']: challenge_type = challenge['type'] token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge['token']) keyauthorization = self.account.get_keyauthorization(token) if challenge_type == 'http-01': # https://tools.ietf.org/html/rfc8555#section-8.3 resource = '.well-known/acme-challenge/' + token data[challenge_type] = { 'resource': resource, 'resource_value': keyauthorization } elif challenge_type == 'dns-01': if identifier_type != 'dns': continue # https://tools.ietf.org/html/rfc8555#section-8.4 resource = '_acme-challenge' value = nopad_b64( hashlib.sha256(to_bytes(keyauthorization)).digest()) record = (resource + identifier[1:]) if identifier.startswith('*.') else ( resource + '.' + identifier) data[challenge_type] = { 'resource': resource, 'resource_value': value, 'record': record } elif challenge_type == 'tls-alpn-01': # https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05#section-3 if identifier_type == 'ip': # IPv4/IPv6 address: use reverse mapping (RFC1034, RFC3596) resource = compat_ipaddress.ip_address( identifier).reverse_pointer if not resource.endswith('.'): resource += '.' else: resource = identifier value = base64.b64encode( hashlib.sha256(to_bytes(keyauthorization)).digest()) data[challenge_type] = { 'resource': resource, 'resource_original': identifier_type + ':' + identifier, 'resource_value': value } else: continue return data
def _normalize_san(self, san): # apperently openssl returns 'IP address' not 'IP' as specifier when converting the subjectAltName to string # although it won't accept this specifier when generating the CSR. (https://github.com/openssl/openssl/issues/4004) if san.startswith('IP Address:'): san = 'IP:' + san[len('IP Address:'):] if san.startswith('IP:'): ip = compat_ipaddress.ip_address(san[3:]) san = 'IP:{0}'.format(ip.compressed) return san
def check_params(self): rules_by_host = {} for host in self.hosts: rules_by_host[host.name] = self.firewall_facts[host.name].keys() for rule_option in self.rule_options: rule_name = rule_option.get('name') if rule_name is None: self.module.fail_json( msg="Please specify rule.name for rule set" " as it is required parameter.") hosts_with_rule_name = [ h for h, r in rules_by_host.items() if rule_name in r ] hosts_without_rule_name = set([i.name for i in self.hosts ]) - set(hosts_with_rule_name) if hosts_without_rule_name: self.module.fail_json( msg="rule named '%s' wasn't found on hosts: %s" % (rule_name, hosts_without_rule_name)) if 'enabled' not in rule_option: self.module.fail_json( msg="Please specify rules.enabled for rule set" " %s as it is required parameter." % rule_name) allowed_hosts = rule_option.get('allowed_hosts', {}) ip_addresses = allowed_hosts.get('ip_address', []) ip_networks = allowed_hosts.get('ip_network', []) for ip_address in ip_addresses: try: ipaddress.ip_address(ip_address) except ValueError: self.module.fail_json( msg="The provided IP address %s is not a valid IP" " for the rule %s" % (ip_address, rule_name)) for ip_network in ip_networks: try: ipaddress.ip_network(ip_network) except ValueError: self.module.fail_json( msg="The provided IP network %s is not a valid network" " for the rule %s" % (ip_network, rule_name))
def _check_subnet(self): """ check if addr lies into interface subnets """ def _check_vips(): virtualips = self.pfsense.get_element('virtualip') if virtualips is None: return False for vip_elt in virtualips: if vip_elt.find( 'interface' ).text != self.interface_elt.tag or vip_elt.find( 'mode').text != 'other' or vip_elt.find( 'type').text != 'network': continue subnet = ip_network(u'{0}/{1}'.format( vip_elt.find('subnet').text, vip_elt.find('subnet_bits').text), strict=False) if addr in subnet: return True return False if self.params['ipprotocol'] == 'inet': inet_type = 'IPv4' f1_elt = self.interface_elt.find('ipaddr') f2_elt = self.interface_elt.find('subnet') else: inet_type = 'IPv6' f1_elt = self.interface_elt.find('ipaddrv6') f2_elt = self.interface_elt.find('subnetv6') if f1_elt is None or f1_elt.text is None or f2_elt is None or f2_elt.text is None: self.module.fail_json( msg= 'Cannot add {0} Gateway Address because no {0} address could be found on the interface.' .format(inet_type)) try: if self.params['nonlocalgateway']: return addr = ip_address(u'{0}'.format(self.params['gateway'])) subnet = ip_network(u'{0}/{1}'.format(f1_elt.text, f2_elt.text), strict=False) if addr in subnet or _check_vips(): return self.module.fail_json( msg= "The gateway address {0} does not lie within one of the chosen interface's subnets." .format(self.params['gateway'])) except ValueError: self.module.fail_json( msg= 'Cannot add {0} Gateway Address because no {0} address could be found on the interface.' .format(inet_type))
def normalize_ip(ip, ip_version): if ip is None: return ip if '/' in ip: ip, range = ip.split('/') else: ip, range = ip, '' ip_addr = to_native(compat_ipaddress.ip_address(to_text(ip)).compressed) if range == '': range = '32' if ip_version.lower() == 'ipv4' else '128' return ip_addr + '/' + range
def is_ipv4_address(data): """ Checks if the passed string is a valid IPv4 address """ if '/' in data: data = data.split('/')[0] if not isipaddress(to_text(data)): raise ValueError('{0} is not a valid IP address'.format(data)) return (ipaddress.ip_address(to_text(data)).version == 4)
def get_ip_address_version(address): """ This function returns the version of IP address :param address: IP address :return: """ try: address = unicode(address) except NameError: address = str(address) version = ipaddress.ip_address(address.split("/")[0]).version return version
def is_within_local_networks(self, address): """ test if address is contained in our local networks """ networks = self.get_interfaces_networks() try: addr = ip_address(u'{0}'.format(address)) except ValueError: return False for network in networks: try: net = ip_network(u'{0}'.format(network), strict=False) if addr in net: return True except ValueError: pass return False
def parse_attribs(self, conf): config = {} ipaddrs = re.findall(r'address (\S+)', conf, re.M) config['ipv4'] = [] config['ipv6'] = [] for item in ipaddrs: item = item.strip("'") if item == 'dhcp': config['ipv4'].append({'address': item}) elif item == 'dhcpv6': config['ipv6'].append({'address': item}) else: ip_version = ipaddress.ip_address(item.split("/")[0]).version if ip_version == 4: config['ipv4'].append({'address': item}) else: config['ipv6'].append({'address': item}) for key, value in iteritems(config): if value == []: config[key] = None return utils.remove_empties(config)
def _normalize_ip(ip): try: return to_native(compat_ipaddress.ip_address(to_text(ip)).compressed) except ValueError: # We don't want to error out on something IPAddress() can't parse return ip
def validate_ip_in_cidr(ip, cidr): address = ipaddress.ip_address(six.u(ip)) network = ipaddress.ip_network(six.u(cidr), strict=False) if address not in network: raise errors.ValidationError("IP {0} not in subnet CIDR {1}.".format( ip, cidr))
def ensure(self): """ Function to ensure rule set configuration """ fw_change_list = [] enable_disable_changed = False allowed_ip_changed = False results = dict(changed=False, rule_set_state=dict()) for host in self.hosts: firewall_system = host.configManager.firewallSystem if firewall_system is None: continue results['rule_set_state'][host.name] = dict() for rule_option in self.rule_options: rule_name = rule_option.get('name', None) if rule_name is None: self.module.fail_json( msg="Please specify rule.name for rule set" " as it is required parameter.") if rule_name not in self.firewall_facts[host.name]: self.module.fail_json(msg="rule named '%s' wasn't found." % rule_name) rule_enabled = rule_option.get('enabled', None) if rule_enabled is None: self.module.fail_json( msg="Please specify rules.enabled for rule set" " %s as it is required parameter." % rule_name) # validate IP addresses are valid rule_config = rule_option.get('allowed_hosts', None) if 'ip_address' in rule_config[0].keys(): for ip_addr in rule_config[0]['ip_address']: try: ip = ipaddress.ip_address(ip_addr) except ValueError: self.module.fail_json( msg= "The provided IP address %s is not a valid IP" " for the rule %s" % (ip_addr, rule_name)) # validate provided subnets are valid networks if 'ip_network' in rule_config[0].keys(): for ip_net in rule_config[0]['ip_network']: try: network_validation = ipaddress.ip_network(ip_net) except ValueError: self.module.fail_json( msg= "The provided network %s is not a valid network" " for the rule %s" % (ip_net, rule_name)) current_rule_state = self.firewall_facts[ host.name][rule_name]['enabled'] if current_rule_state != rule_enabled: try: if not self.module.check_mode: if rule_enabled: firewall_system.EnableRuleset(id=rule_name) else: firewall_system.DisableRuleset(id=rule_name) # keep track of changes as we go enable_disable_changed = True except vim.fault.NotFound as not_found: self.module.fail_json( msg="Failed to enable rule set %s as" " rule set id is unknown : %s" % (rule_name, to_native(not_found.msg))) except vim.fault.HostConfigFault as host_config_fault: self.module.fail_json( msg="Failed to enabled rule set %s as an internal" " error happened while reconfiguring" " rule set : %s" % (rule_name, to_native(host_config_fault.msg))) # save variables here for comparison later and change tracking # also covers cases where inputs may be null permitted_networking = self.firewall_facts[ host.name][rule_name] rule_allows_all = permitted_networking['allowed_hosts'][ 'all_ip'] playbook_allows_all = rule_config[0]['all_ip'] rule_allowed_ip = set( permitted_networking['allowed_hosts']['ip_address']) playbook_allowed_ip = set(rule_config[0].get('ip_address', '')) rule_allowed_networks = set( permitted_networking['allowed_hosts']['ip_network']) playbook_allowed_networks = set(rule_config[0].get( 'ip_network', '')) # compare what is configured on the firewall rule with what the playbook provides allowed_all_ips_different = bool( rule_allows_all != playbook_allows_all) ip_list_different = bool( rule_allowed_ip != playbook_allowed_ip) ip_network_different = bool( rule_allowed_networks != playbook_allowed_networks) # apply everything here in one function call if allowed_all_ips_different is True or ip_list_different is True or ip_network_different is True: try: allowed_ip_changed = True if not self.module.check_mode: # setup spec firewall_spec = vim.host.Ruleset.RulesetSpec() firewall_spec.allowedHosts = vim.host.Ruleset.IpList( ) firewall_spec.allowedHosts.allIp = rule_config[ 0].get('all_ip', True) firewall_spec.allowedHosts.ipAddress = rule_config[ 0].get('ip_address', None) firewall_spec.allowedHosts.ipNetwork = [] if 'ip_network' in rule_config[0].keys(): for allowed_network in rule_config[0].get( 'ip_network', None): tmp_ip_network_spec = vim.host.Ruleset.IpNetwork( ) tmp_ip_network_spec.network = allowed_network.split( "/")[0] tmp_ip_network_spec.prefixLength = int( allowed_network.split("/")[1]) firewall_spec.allowedHosts.ipNetwork.append( tmp_ip_network_spec) firewall_system.UpdateRuleset(id=rule_name, spec=firewall_spec) except vim.fault.NotFound as not_found: self.module.fail_json( msg="Failed to configure rule set %s as" " rule set id is unknown : %s" % (rule_name, to_native(not_found.msg))) except vim.fault.HostConfigFault as host_config_fault: self.module.fail_json( msg="Failed to configure rule set %s as an internal" " error happened while reconfiguring" " rule set : %s" % (rule_name, to_native(host_config_fault.msg))) except vim.fault.RuntimeFault as runtime_fault: self.module.fail_json( msg= "Failed to configure the rule set %s as a runtime" " error happened while applying the reconfiguration:" " %s" % (rule_name, to_native(runtime_fault.msg))) results['rule_set_state'][host.name][rule_name] = dict( current_state=rule_enabled, previous_state=current_rule_state, desired_state=rule_enabled, current_allowed_all=playbook_allows_all, previous_allowed_all=permitted_networking['allowed_hosts'] ['all_ip'], desired_allowed_all=playbook_allows_all, current_allowed_ip=playbook_allowed_ip, previous_allowed_ip=set( permitted_networking['allowed_hosts']['ip_address']), desired_allowed_ip=playbook_allowed_ip, current_allowed_networks=playbook_allowed_networks, previous_allowed_networks=set( permitted_networking['allowed_hosts']['ip_network']), desired_allowed_networks=playbook_allowed_networks) if enable_disable_changed or allowed_ip_changed: fw_change_list.append(True) if any(fw_change_list): results['changed'] = True self.module.exit_json(**results)